├── .gitignore ├── .travis.yml ├── AndroidManifest.xml ├── LICENSE ├── README.md ├── build.gradle ├── docs ├── allclasses-frame.html ├── allclasses-noframe.html ├── com │ └── alipay │ │ └── euler │ │ └── andfix │ │ └── patch │ │ ├── PatchManager.html │ │ ├── package-frame.html │ │ ├── package-summary.html │ │ └── package-tree.html ├── constant-values.html ├── deprecated-list.html ├── help-doc.html ├── index-all.html ├── index.html ├── overview-tree.html ├── package-list ├── resources │ ├── background.gif │ ├── tab.gif │ ├── titlebar.gif │ └── titlebar_end.gif └── stylesheet.css ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── images ├── license.svg ├── principle.png └── process.png ├── jni ├── Android.mk ├── Application.mk ├── andfix.cpp ├── art │ ├── art.h │ ├── art_4_4.h │ ├── art_5_0.h │ ├── art_5_1.h │ ├── art_6_0.h │ ├── art_7_0.h │ ├── art_method_replace.cpp │ ├── art_method_replace_4_4.cpp │ ├── art_method_replace_5_0.cpp │ ├── art_method_replace_5_1.cpp │ ├── art_method_replace_6_0.cpp │ └── art_method_replace_7_0.cpp ├── common.h └── dalvik │ ├── dalvik.h │ └── dalvik_method_replace.cpp ├── libs ├── arm64-v8a │ └── libandfix.so ├── armeabi-v7a │ └── libandfix.so ├── armeabi │ └── libandfix.so ├── mips │ └── libandfix.so ├── mips64 │ └── libandfix.so ├── x86 │ └── libandfix.so └── x86_64 │ └── libandfix.so ├── local.properties ├── proguard-project.txt ├── samples └── AndFixDemo │ ├── .gitignore │ ├── AndroidManifest.xml │ ├── ic_launcher-web.png │ ├── proguard-project.txt │ ├── res │ ├── drawable-hdpi │ │ └── ic_launcher.png │ ├── drawable-ldpi │ │ └── ic_launcher.png │ ├── drawable-mdpi │ │ └── ic_launcher.png │ ├── drawable-xhdpi │ │ └── ic_launcher.png │ ├── drawable-xxhdpi │ │ └── ic_launcher.png │ ├── layout │ │ └── main.xml │ └── values │ │ └── strings.xml │ └── src │ └── com │ └── euler │ ├── andfix │ ├── MainActivity.java │ └── MainApplication.java │ └── test │ ├── A.java │ ├── F.java │ ├── Fix.java │ └── O.java ├── settings.gradle ├── src └── com │ └── alipay │ └── euler │ └── andfix │ ├── AndFix.java │ ├── AndFixManager.java │ ├── Compat.java │ ├── annotation │ └── MethodReplace.java │ ├── patch │ ├── Patch.java │ └── PatchManager.java │ ├── security │ └── SecurityChecker.java │ └── util │ └── FileUtil.java └── tools └── apkpatch-1.0.3.zip /.gitignore: -------------------------------------------------------------------------------- 1 | # Built application files 2 | *.apk 3 | *.ap_ 4 | 5 | # Files for the Dalvik VM 6 | *.dex 7 | 8 | # Java class files 9 | *.class 10 | 11 | # Generated files 12 | bin/ 13 | gen/ 14 | 15 | # Gradle files 16 | .gradle/ 17 | build/ 18 | /*/build/ 19 | 20 | # Local configuration file (sdk path, etc) 21 | 22 | # Proguard folder generated by Eclipse 23 | proguard/ 24 | 25 | # Log Files 26 | *.log 27 | 28 | .DS_Store 29 | .classpath 30 | .project 31 | /.settings 32 | /bin 33 | /build 34 | /gen 35 | /obj 36 | project.properties 37 | /assets 38 | /res 39 | /dist 40 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: android 2 | jdk: oraclejdk7 3 | env: 4 | matrix: 5 | - ANDROID_TARGET=android-19 ANDROID_ABI=armeabi-v7a 6 | 7 | android: 8 | components: 9 | - build-tools-22.0.1 10 | 11 | before_script: 12 | # Create and start emulator 13 | - echo no | android create avd --force -n test -t $ANDROID_TARGET --abi $ANDROID_ABI 14 | - emulator -avd test -no-skin -no-audio -no-window & 15 | - adb wait-for-device 16 | - adb shell input keyevent 82 & 17 | 18 | script: ./gradlew connectedAndroidTest 19 | 20 | after_script: ./gradlew bintrayUpload -------------------------------------------------------------------------------- /AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015, alipay.com 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | 6 | Unless required by applicable law or agreed to in writing, software 7 | distributed under the License is distributed on an "AS IS" BASIS, 8 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 9 | See the License for the specific language governing permissions and 10 | limitations under the License. 11 | 12 | 13 | Apache License 14 | Version 2.0, January 2004 15 | http://www.apache.org/licenses/ 16 | 17 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 18 | 19 | 1. Definitions. 20 | 21 | "License" shall mean the terms and conditions for use, reproduction, 22 | and distribution as defined by Sections 1 through 9 of this document. 23 | 24 | "Licensor" shall mean the copyright owner or entity authorized by 25 | the copyright owner that is granting the License. 26 | 27 | "Legal Entity" shall mean the union of the acting entity and all 28 | other entities that control, are controlled by, or are under common 29 | control with that entity. For the purposes of this definition, 30 | "control" means (i) the power, direct or indirect, to cause the 31 | direction or management of such entity, whether by contract or 32 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 33 | outstanding shares, or (iii) beneficial ownership of such entity. 34 | 35 | "You" (or "Your") shall mean an individual or Legal Entity 36 | exercising permissions granted by this License. 37 | 38 | "Source" form shall mean the preferred form for making modifications, 39 | including but not limited to software source code, documentation 40 | source, and configuration files. 41 | 42 | "Object" form shall mean any form resulting from mechanical 43 | transformation or translation of a Source form, including but 44 | not limited to compiled object code, generated documentation, 45 | and conversions to other media types. 46 | 47 | "Work" shall mean the work of authorship, whether in Source or 48 | Object form, made available under the License, as indicated by a 49 | copyright notice that is included in or attached to the work 50 | (an example is provided in the Appendix below). 51 | 52 | "Derivative Works" shall mean any work, whether in Source or Object 53 | form, that is based on (or derived from) the Work and for which the 54 | editorial revisions, annotations, elaborations, or other modifications 55 | represent, as a whole, an original work of authorship. For the purposes 56 | of this License, Derivative Works shall not include works that remain 57 | separable from, or merely link (or bind by name) to the interfaces of, 58 | the Work and Derivative Works thereof. 59 | 60 | "Contribution" shall mean any work of authorship, including 61 | the original version of the Work and any modifications or additions 62 | to that Work or Derivative Works thereof, that is intentionally 63 | submitted to Licensor for inclusion in the Work by the copyright owner 64 | or by an individual or Legal Entity authorized to submit on behalf of 65 | the copyright owner. For the purposes of this definition, "submitted" 66 | means any form of electronic, verbal, or written communication sent 67 | to the Licensor or its representatives, including but not limited to 68 | communication on electronic mailing lists, source code control systems, 69 | and issue tracking systems that are managed by, or on behalf of, the 70 | Licensor for the purpose of discussing and improving the Work, but 71 | excluding communication that is conspicuously marked or otherwise 72 | designated in writing by the copyright owner as "Not a Contribution." 73 | 74 | "Contributor" shall mean Licensor and any individual or Legal Entity 75 | on behalf of whom a Contribution has been received by Licensor and 76 | subsequently incorporated within the Work. 77 | 78 | 2. Grant of Copyright License. Subject to the terms and conditions of 79 | this License, each Contributor hereby grants to You a perpetual, 80 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 81 | copyright license to reproduce, prepare Derivative Works of, 82 | publicly display, publicly perform, sublicense, and distribute the 83 | Work and such Derivative Works in Source or Object form. 84 | 85 | 3. Grant of Patent License. Subject to the terms and conditions of 86 | this License, each Contributor hereby grants to You a perpetual, 87 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 88 | (except as stated in this section) patent license to make, have made, 89 | use, offer to sell, sell, import, and otherwise transfer the Work, 90 | where such license applies only to those patent claims licensable 91 | by such Contributor that are necessarily infringed by their 92 | Contribution(s) alone or by combination of their Contribution(s) 93 | with the Work to which such Contribution(s) was submitted. If You 94 | institute patent litigation against any entity (including a 95 | cross-claim or counterclaim in a lawsuit) alleging that the Work 96 | or a Contribution incorporated within the Work constitutes direct 97 | or contributory patent infringement, then any patent licenses 98 | granted to You under this License for that Work shall terminate 99 | as of the date such litigation is filed. 100 | 101 | 4. Redistribution. You may reproduce and distribute copies of the 102 | Work or Derivative Works thereof in any medium, with or without 103 | modifications, and in Source or Object form, provided that You 104 | meet the following conditions: 105 | 106 | (a) You must give any other recipients of the Work or 107 | Derivative Works a copy of this License; and 108 | 109 | (b) You must cause any modified files to carry prominent notices 110 | stating that You changed the files; and 111 | 112 | (c) You must retain, in the Source form of any Derivative Works 113 | that You distribute, all copyright, patent, trademark, and 114 | attribution notices from the Source form of the Work, 115 | excluding those notices that do not pertain to any part of 116 | the Derivative Works; and 117 | 118 | (d) If the Work includes a "NOTICE" text file as part of its 119 | distribution, then any Derivative Works that You distribute must 120 | include a readable copy of the attribution notices contained 121 | within such NOTICE file, excluding those notices that do not 122 | pertain to any part of the Derivative Works, in at least one 123 | of the following places: within a NOTICE text file distributed 124 | as part of the Derivative Works; within the Source form or 125 | documentation, if provided along with the Derivative Works; or, 126 | within a display generated by the Derivative Works, if and 127 | wherever such third-party notices normally appear. The contents 128 | of the NOTICE file are for informational purposes only and 129 | do not modify the License. You may add Your own attribution 130 | notices within Derivative Works that You distribute, alongside 131 | or as an addendum to the NOTICE text from the Work, provided 132 | that such additional attribution notices cannot be construed 133 | as modifying the License. 134 | 135 | You may add Your own copyright statement to Your modifications and 136 | may provide additional or different license terms and conditions 137 | for use, reproduction, or distribution of Your modifications, or 138 | for any such Derivative Works as a whole, provided Your use, 139 | reproduction, and distribution of the Work otherwise complies with 140 | the conditions stated in this License. 141 | 142 | 5. Submission of Contributions. Unless You explicitly state otherwise, 143 | any Contribution intentionally submitted for inclusion in the Work 144 | by You to the Licensor shall be under the terms and conditions of 145 | this License, without any additional terms or conditions. 146 | Notwithstanding the above, nothing herein shall supersede or modify 147 | the terms of any separate license agreement you may have executed 148 | with Licensor regarding such Contributions. 149 | 150 | 6. Trademarks. This License does not grant permission to use the trade 151 | names, trademarks, service marks, or product names of the Licensor, 152 | except as required for reasonable and customary use in describing the 153 | origin of the Work and reproducing the content of the NOTICE file. 154 | 155 | 7. Disclaimer of Warranty. Unless required by applicable law or 156 | agreed to in writing, Licensor provides the Work (and each 157 | Contributor provides its Contributions) on an "AS IS" BASIS, 158 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 159 | implied, including, without limitation, any warranties or conditions 160 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 161 | PARTICULAR PURPOSE. You are solely responsible for determining the 162 | appropriateness of using or redistributing the Work and assume any 163 | risks associated with Your exercise of permissions under this License. 164 | 165 | 8. Limitation of Liability. In no event and under no legal theory, 166 | whether in tort (including negligence), contract, or otherwise, 167 | unless required by applicable law (such as deliberate and grossly 168 | negligent acts) or agreed to in writing, shall any Contributor be 169 | liable to You for damages, including any direct, indirect, special, 170 | incidental, or consequential damages of any character arising as a 171 | result of this License or out of the use or inability to use the 172 | Work (including but not limited to damages for loss of goodwill, 173 | work stoppage, computer failure or malfunction, or any and all 174 | other commercial damages or losses), even if such Contributor 175 | has been advised of the possibility of such damages. 176 | 177 | 9. Accepting Warranty or Additional Liability. While redistributing 178 | the Work or Derivative Works thereof, You may choose to offer, 179 | and charge a fee for, acceptance of support, warranty, indemnity, 180 | or other liability obligations and/or rights consistent with this 181 | License. However, in accepting such obligations, You may act only 182 | on Your own behalf and on Your sole responsibility, not on behalf 183 | of any other Contributor, and only if You agree to indemnify, 184 | defend, and hold each Contributor harmless for any liability 185 | incurred by, or claims asserted against, such Contributor by reason 186 | of your accepting any such warranty or additional liability. 187 | 188 | END OF TERMS AND CONDITIONS -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # AndFix 2 | 3 | [![Download](https://api.bintray.com/packages/supern/maven/andfix/images/download.svg) ](https://bintray.com/supern/maven/andfix/_latestVersion) 4 | [![Build Status](https://travis-ci.org/alibaba/AndFix.svg)](https://travis-ci.org/alibaba/AndFix) 5 | [![Software License](https://rawgit.com/alibaba/AndFix/master/images/license.svg)](LICENSE) 6 | 7 | [![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/alibaba/AndFix?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) 8 | 9 | AndFix is a solution to fix the bugs online instead of redistributing Android App. It is distributed as [Android Library](https://sites.google.com/a/android.com/tools/tech-docs/new-build-system/aar-format). 10 | 11 | Andfix is an acronym for "**And**roid hot-**fix**". 12 | 13 | AndFix supports Android version from 2.3 to 7.0, both ARM and X86 architecture, both Dalvik and ART runtime, both 32bit and 64bit. 14 | 15 | The compressed file format of AndFix's patch is **.apatch**. It is dispatched from your own server to client to fix your App's bugs. 16 | 17 | ## Principle 18 | 19 | The implementation principle of AndFix is method body's replacing, 20 | 21 | ![image](images/principle.png) 22 | 23 | ### Method replacing 24 | 25 | AndFix judges the methods should be replaced by java custom annotation and replaces it by hooking it. AndFix has a native method `art_replaceMethod` in ART or `dalvik_replaceMethod` in Dalvik. 26 | 27 | For more details, [here](https://github.com/alibaba/AndFix/tree/master/jni). 28 | 29 | ## Fix Process 30 | 31 | ![image](images/process.png) 32 | 33 | ## Integration 34 | 35 | ### How to get? 36 | 37 | Directly add AndFix aar to your project as compile libraries. 38 | 39 | For your maven dependency, 40 | 41 | ```xml 42 | 43 | com.alipay.euler 44 | andfix 45 | 0.5.0 46 | aar 47 | 48 | ``` 49 | For your gradle dependency, 50 | 51 | ```groovy 52 | dependencies { 53 | compile 'com.alipay.euler:andfix:0.5.0@aar' 54 | } 55 | ``` 56 | 57 | ### How to use? 58 | 59 | 1. Initialize PatchManager, 60 | 61 | ```java 62 | patchManager = new PatchManager(context); 63 | patchManager.init(appversion);//current version 64 | ``` 65 | 66 | 2. Load patch, 67 | 68 | ```java 69 | patchManager.loadPatch(); 70 | ``` 71 | 72 | You should load patch as early as possible, generally, in the initialization phase of your application(such as `Application.onCreate()`). 73 | 74 | 3. Add patch, 75 | 76 | ```java 77 | patchManager.addPatch(path);//path of the patch file that was downloaded 78 | ``` 79 | When a new patch file has been downloaded, it will become effective immediately by `addPatch`. 80 | 81 | ## Developer Tool 82 | 83 | AndFix provides a patch-making tool called **apkpatch**. 84 | 85 | ### How to get? 86 | 87 | The `apkpatch` tool can be found [here](https://github.com/alibaba/AndFix/raw/master/tools/apkpatch-1.0.3.zip). 88 | 89 | ### How to use? 90 | 91 | * Prepare two android packages, one is the online package, the other one is the package after you fix bugs by coding. 92 | 93 | * Generate `.apatch` file by providing the two package, 94 | 95 | ``` 96 | usage: apkpatch -f -t -o -k -p <***> -a -e <***> 97 | -a,--alias keystore entry alias. 98 | -e,--epassword <***> keystore entry password. 99 | -f,--from new Apk file path. 100 | -k,--keystore keystore path. 101 | -n,--name patch name. 102 | -o,--out output dir. 103 | -p,--kpassword <***> keystore password. 104 | -t,--to old Apk file path. 105 | ``` 106 | 107 | Now you get the application savior, the patch file. Then you need to dispatch it to your client in some way, push or pull. 108 | 109 | Sometimes, your team members may fix each other's bugs, and generate not only one `.apatch`. For this situation, you can 110 | merge `.apatch` files using this tool, 111 | 112 | ``` 113 | usage: apkpatch -m -o -k -p <***> -a -e <***> 114 | -a,--alias keystore entry alias. 115 | -e,--epassword <***> keystore entry password. 116 | -k,--keystore keystore path. 117 | -m,--merge path of .apatch files. 118 | -n,--name patch name. 119 | -o,--out output dir. 120 | -p,--kpassword <***> keystore password. 121 | ``` 122 | 123 | ## Running sample 124 | 125 | 1. Import samplesI/AndFixDemo to your IDE, append AndFixDemo dependencies with AndFix(library project or aar). 126 | 2. Build project, save the package as 1.apk, and then install on device/emulator. 127 | 3. Modify com.euler.test.A, references com.euler.test.Fix. 128 | 4. Build project, save the package as 2.apk. 129 | 5. Use apkpatch tool to make a patch. 130 | 6. Rename the patch file to out.apatch, and then copy it to sdcard. 131 | 7. Run 1.apk and view log. 132 | 133 | ## Notice 134 | 135 | ### ProGuard 136 | 137 | If you enable ProGuard, you must save the mapping.txt, so your new version's build can use it with ["-applymapping"](http://proguard.sourceforge.net/manual/usage.html#applymapping). 138 | 139 | And it is necessary to keep classes as follow, 140 | 141 | * Native method 142 | 143 | com.alipay.euler.andfix.AndFix 144 | 145 | * Annotation 146 | 147 | com.alipay.euler.andfix.annotation.MethodReplace 148 | 149 | To ensure that these classes can be found after running an obfuscation and static analysis tool like ProGuard, add the configuration below to your ProGuard configuration file. 150 | 151 | 152 | ``` 153 | -keep class * extends java.lang.annotation.Annotation 154 | -keepclasseswithmembernames class * { 155 | native ; 156 | } 157 | ``` 158 | 159 | ### Self-Modifying Code 160 | 161 | If you use it, such as *Bangcle*. To generate patch file, you'd better to use raw apk. 162 | 163 | ### Security 164 | 165 | The following is important but out of AndFix's range. 166 | 167 | - verify the signature of patch file 168 | - verify the fingerprint of optimize file 169 | 170 | ## API Documentation 171 | 172 | The libraries javadoc can be found [here](https://rawgit.com/alibaba/AndFix/master/docs/index.html). 173 | 174 | ## Contact 175 | 176 | ... 177 | 178 | ## License 179 | 180 | [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.html) 181 | 182 | Copyright (c) 2015, alipay.com 183 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | repositories { 3 | jcenter() 4 | } 5 | 6 | dependencies { 7 | classpath 'com.android.tools.build:gradle:1.3.0' 8 | classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.2' 9 | classpath 'com.github.dcendents:android-maven-gradle-plugin:1.3' 10 | } 11 | } 12 | 13 | apply plugin: 'com.android.library' 14 | 15 | android { 16 | compileSdkVersion 19 17 | buildToolsVersion "22.0.1" 18 | 19 | sourceSets { 20 | main { 21 | manifest { 22 | srcFile 'AndroidManifest.xml' 23 | } 24 | java { 25 | srcDir 'src' 26 | } 27 | res { 28 | srcDir 'res' 29 | } 30 | assets { 31 | srcDir 'assets' 32 | } 33 | resources { 34 | srcDir 'src' 35 | } 36 | aidl { 37 | srcDir 'src' 38 | } 39 | jniLibs{ 40 | srcDirs 'libs' 41 | } 42 | } 43 | } 44 | } 45 | 46 | ext { 47 | bintrayRepo = 'maven' 48 | bintrayName = 'andfix' 49 | 50 | publishedGroupId = 'com.alipay.euler' 51 | libraryName = 'andfix' 52 | artifact = 'andfix' 53 | 54 | libraryDescription = 'AndFix is a library that offer hot-fix for Android App. ' 55 | 56 | siteUrl = 'https://github.com/alibaba/AndFix' 57 | gitUrl = 'https://github.com/alibaba/AndFix.git' 58 | 59 | libraryVersion = '0.5.0' 60 | 61 | developerId = 'supern' 62 | developerName = 'Supern Lee' 63 | developerEmail = 'supern.lee@gmail.com' 64 | 65 | licenseName = 'The Apache Software License, Version 2.0' 66 | licenseUrl = 'http://www.apache.org/licenses/LICENSE-2.0.txt' 67 | allLicenses = ["Apache-2.0"] 68 | } 69 | 70 | android.libraryVariants.all { variant -> 71 | task("generate${variant.name.capitalize()}Javadoc", type: Javadoc) { 72 | title = 'AndFix API' 73 | // description = '' 74 | source = variant.javaCompile.source 75 | classpath = files(variant.javaCompile.classpath.files, project.android.getBootClasspath()) 76 | options { 77 | links "http://docs.oracle.com/javase/7/docs/api/" 78 | linksOffline "http://d.android.com/reference","${android.sdkDirectory}/docs/reference" 79 | } 80 | exclude '**/BuildConfig.java' 81 | exclude '**/R.java' 82 | include 'com/alipay/euler/andfix/patch/PatchManager.java' 83 | } 84 | } 85 | 86 | apply from: 'https://raw.githubusercontent.com/attwellBrian/JCenter/master/installv1.gradle' 87 | apply from: 'https://raw.githubusercontent.com/attwellBrian/JCenter/master/bintrayv1.gradle' 88 | -------------------------------------------------------------------------------- /docs/allclasses-frame.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 所有类 (AndFix API) 7 | 8 | 9 | 10 | 11 |

所有类

12 |
13 | 16 |
17 | 18 | 19 | -------------------------------------------------------------------------------- /docs/allclasses-noframe.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 所有类 (AndFix API) 7 | 8 | 9 | 10 | 11 |

所有类

12 |
13 | 16 |
17 | 18 | 19 | -------------------------------------------------------------------------------- /docs/com/alipay/euler/andfix/patch/package-frame.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | com.alipay.euler.andfix.patch (AndFix API) 7 | 8 | 9 | 10 | 11 |

com.alipay.euler.andfix.patch

12 |
13 |

14 | 17 |
18 | 19 | 20 | -------------------------------------------------------------------------------- /docs/com/alipay/euler/andfix/patch/package-summary.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | com.alipay.euler.andfix.patch (AndFix API) 7 | 8 | 9 | 10 | 11 | 17 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 34 |
35 | 62 | 63 |
64 |

程序包 com.alipay.euler.andfix.patch

65 |
66 |
67 |
    68 |
  • 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 81 | 82 | 83 |
    类概要 
    说明
    PatchManager 79 |
    patch manager
    80 |
    84 |
  • 85 |
86 |
87 | 88 |
89 | 90 | 91 | 92 | 93 | 101 |
102 | 129 | 130 | 131 | 132 | -------------------------------------------------------------------------------- /docs/com/alipay/euler/andfix/patch/package-tree.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | com.alipay.euler.andfix.patch 类分层结构 (AndFix API) 7 | 8 | 9 | 10 | 11 | 17 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 34 |
35 | 62 | 63 |
64 |

程序包com.alipay.euler.andfix.patch的分层结构

65 |
66 |
67 |

类分层结构

68 |
    69 |
  • java.lang.Object 70 | 73 |
  • 74 |
75 |
76 | 77 |
78 | 79 | 80 | 81 | 82 | 90 |
91 | 118 | 119 | 120 | 121 | -------------------------------------------------------------------------------- /docs/constant-values.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 常量字段值 (AndFix API) 7 | 8 | 9 | 10 | 11 | 17 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 34 |
35 | 62 | 63 |
64 |

常量字段值

65 |

目录

66 |
67 | 68 |
69 | 70 | 71 | 72 | 73 | 81 |
82 | 109 | 110 | 111 | 112 | -------------------------------------------------------------------------------- /docs/deprecated-list.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 已过时的列表 (AndFix API) 7 | 8 | 9 | 10 | 11 | 17 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 34 |
35 | 62 | 63 |
64 |

已过时的 API

65 |

目录

66 |
67 | 68 |
69 | 70 | 71 | 72 | 73 | 81 |
82 | 109 | 110 | 111 | 112 | -------------------------------------------------------------------------------- /docs/help-doc.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | API 帮助 (AndFix API) 7 | 8 | 9 | 10 | 11 | 17 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 34 |
35 | 62 | 63 |
64 |

此 API 文档的组织方式

65 |
此 API (应用程序编程接口) 文档包含对应于导航栏中的项目的页面, 如下所述。
66 |
67 |
68 |
    69 |
  • 70 |

    程序包

    71 |

    每个程序包都有一个页面, 其中包含它的类和接口的列表及其概要。此页面可以包含六个类别:

    72 |
      73 |
    • 接口 (斜体)
    • 74 |
    • 75 |
    • 枚举
    • 76 |
    • 异常错误
    • 77 |
    • 错误
    • 78 |
    • 注释类型
    • 79 |
    80 |
  • 81 |
  • 82 |

    类/接口

    83 |

    每个类, 接口, 嵌套类和嵌套接口都有各自的页面。其中每个页面都由三部分 (类/接口说明, 概要表, 以及详细的成员说明) 组成:

    84 |
      85 |
    • 类继承图
    • 86 |
    • 直接子类
    • 87 |
    • 所有已知子接口
    • 88 |
    • 所有已知实现类
    • 89 |
    • 类/接口声明
    • 90 |
    • 类/接口说明
    • 91 |
    92 |
      93 |
    • 嵌套类概要
    • 94 |
    • 字段概要
    • 95 |
    • 构造器概要
    • 96 |
    • 方法概要
    • 97 |
    98 |
      99 |
    • 字段详细资料
    • 100 |
    • 构造器详细资料
    • 101 |
    • 方法详细资料
    • 102 |
    103 |

    每个概要条目都包含该项目的详细说明的第一句。概要条目按字母顺序排列, 而详细说明则按其在源代码中出现的顺序排列。这样保持了程序员所建立的逻辑分组。

    104 |
  • 105 |
  • 106 |

    注释类型

    107 |

    每个注释类型都有各自的页面, 其中包含以下部分:

    108 |
      109 |
    • 注释类型声明
    • 110 |
    • 注释类型说明
    • 111 |
    • 必需元素概要
    • 112 |
    • 可选元素概要
    • 113 |
    • 元素详细资料
    • 114 |
    115 |
  • 116 |
  • 117 |

    枚举

    118 |

    每个枚举都有各自的页面, 其中包含以下部分:

    119 |
      120 |
    • 枚举声明
    • 121 |
    • 枚举说明
    • 122 |
    • 枚举常量概要
    • 123 |
    • 枚举常量详细资料
    • 124 |
    125 |
  • 126 |
  • 127 |

    树 (类分层结构)

    128 |

    对于所有程序包, 有一个 类分层结构 页面, 以及每个程序包的分层结构。每个分层结构页面都包含类的列表和接口的列表。从 java.lang.Object 开始, 按继承结构对类进行排列。接口不从 java.lang.Object 继承。

    129 |
      130 |
    • 查看“概览”页面时, 单击 "树" 将显示所有程序包的分层结构。
    • 131 |
    • 查看特定程序包, 类或接口页面时, 单击 "树" 将仅显示该程序包的分层结构。
    • 132 |
    133 |
  • 134 |
  • 135 |

    已过时的 API

    136 |

    已过时的 API 页面列出了所有已过时的 API。一般由于进行了改进并且通常提供了替代的 API, 所以建议不要使用已过时的 API。在将来的实现过程中, 可能会删除已过时的 API。

    137 |
  • 138 |
  • 139 |

    索引

    140 |

    索引 包含按字母顺序排列的所有类, 接口, 构造器, 方法和字段的列表。

    141 |
  • 142 |
  • 143 |

    上一个/下一个

    144 |

    这些链接使您可以转至下一个或上一个类, 接口, 程序包或相关页面。

    145 |
  • 146 |
  • 147 |

    框架/无框架

    148 |

    这些链接用于显示和隐藏 HTML 框架。所有页面均具有有框架和无框架两种显示方式。

    149 |
  • 150 |
  • 151 |

    所有类

    152 |

    所有类链接显示所有类和接口 (除了非静态嵌套类型)。

    153 |
  • 154 |
  • 155 |

    序列化表格

    156 |

    每个可序列化或可外部化的类都有其序列化字段和方法的说明。此信息对重新实现者有用, 而对使用 API 的开发者则没有什么用处。尽管导航栏中没有链接, 但您可以通过下列方式获取此信息: 转至任何序列化类, 然后单击类说明的 "另请参阅" 部分中的 "序列化表格"。

    157 |
  • 158 |
  • 159 |

    常量字段值

    160 |

    常量字段值页面列出了静态最终字段及其值。

    161 |
  • 162 |
163 | 此帮助文件适用于使用标准 doclet 生成的 API 文档。
164 | 165 |
166 | 167 | 168 | 169 | 170 | 178 |
179 | 206 | 207 | 208 | 209 | -------------------------------------------------------------------------------- /docs/index-all.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 索引 (AndFix API) 7 | 8 | 9 | 10 | 11 | 17 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 34 |
35 | 62 | 63 |
A C I L P R  64 | 65 | 66 |

A

67 |
68 |
addPatch(String) - 类 中的方法com.alipay.euler.andfix.patch.PatchManager
69 |
70 |
add patch at runtime
71 |
72 |
73 | 74 | 75 | 76 |

C

77 |
78 |
com.alipay.euler.andfix.patch - 程序包 com.alipay.euler.andfix.patch
79 |
 
80 |
81 | 82 | 83 | 84 |

I

85 |
86 |
init(String) - 类 中的方法com.alipay.euler.andfix.patch.PatchManager
87 |
88 |
initialize
89 |
90 |
91 | 92 | 93 | 94 |

L

95 |
96 |
loadPatch(String, ClassLoader) - 类 中的方法com.alipay.euler.andfix.patch.PatchManager
97 |
98 |
load patch,call when plugin be loaded. used for plugin architecture.
99 |
100 |
loadPatch() - 类 中的方法com.alipay.euler.andfix.patch.PatchManager
101 |
102 |
load patch,call when application start
103 |
104 |
105 | 106 | 107 | 108 |

P

109 |
110 |
PatchManager - com.alipay.euler.andfix.patch中的类
111 |
112 |
patch manager
113 |
114 |
PatchManager(Context) - 类 的构造器com.alipay.euler.andfix.patch.PatchManager
115 |
 
116 |
117 | 118 | 119 | 120 |

R

121 |
122 |
removeAllPatch() - 类 中的方法com.alipay.euler.andfix.patch.PatchManager
123 |
124 |
remove all patchs
125 |
126 |
127 | A C I L P R 
128 | 129 |
130 | 131 | 132 | 133 | 134 | 142 |
143 | 170 | 171 | 172 | 173 | -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | AndFix API 7 | 52 | 53 | 54 | 55 | 56 | 57 | <noscript> 58 | <div>您的浏览器已禁用 JavaScript。</div> 59 | </noscript> 60 | <h2>框架预警</h2> 61 | <p>请使用框架功能查看此文档。如果看到此消息, 则表明您使用的是不支持框架的 Web 客户机。链接到<a href="com/alipay/euler/andfix/patch/package-summary.html">非框架版本</a>。</p> 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /docs/overview-tree.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 类分层结构 (AndFix API) 7 | 8 | 9 | 10 | 11 | 17 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 34 |
35 | 62 | 63 |
64 |

所有程序包的分层结构

65 | 程序包分层结构: 66 | 69 |
70 |
71 |

类分层结构

72 |
    73 |
  • java.lang.Object 74 | 77 |
  • 78 |
79 |
80 | 81 |
82 | 83 | 84 | 85 | 86 | 94 |
95 | 122 | 123 | 124 | 125 | -------------------------------------------------------------------------------- /docs/package-list: -------------------------------------------------------------------------------- 1 | com.alipay.euler.andfix.patch 2 | -------------------------------------------------------------------------------- /docs/resources/background.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alibaba/AndFix/0351a4bc38a7d30bc61a6d3e74777d4eff4ad5e9/docs/resources/background.gif -------------------------------------------------------------------------------- /docs/resources/tab.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alibaba/AndFix/0351a4bc38a7d30bc61a6d3e74777d4eff4ad5e9/docs/resources/tab.gif -------------------------------------------------------------------------------- /docs/resources/titlebar.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alibaba/AndFix/0351a4bc38a7d30bc61a6d3e74777d4eff4ad5e9/docs/resources/titlebar.gif -------------------------------------------------------------------------------- /docs/resources/titlebar_end.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alibaba/AndFix/0351a4bc38a7d30bc61a6d3e74777d4eff4ad5e9/docs/resources/titlebar_end.gif -------------------------------------------------------------------------------- /docs/stylesheet.css: -------------------------------------------------------------------------------- 1 | /* Javadoc style sheet */ 2 | /* 3 | Overall document style 4 | */ 5 | body { 6 | background-color:#ffffff; 7 | color:#353833; 8 | font-family:Arial, Helvetica, sans-serif; 9 | font-size:76%; 10 | margin:0; 11 | } 12 | a:link, a:visited { 13 | text-decoration:none; 14 | color:#4c6b87; 15 | } 16 | a:hover, a:focus { 17 | text-decoration:none; 18 | color:#bb7a2a; 19 | } 20 | a:active { 21 | text-decoration:none; 22 | color:#4c6b87; 23 | } 24 | a[name] { 25 | color:#353833; 26 | } 27 | a[name]:hover { 28 | text-decoration:none; 29 | color:#353833; 30 | } 31 | pre { 32 | font-size:1.3em; 33 | } 34 | h1 { 35 | font-size:1.8em; 36 | } 37 | h2 { 38 | font-size:1.5em; 39 | } 40 | h3 { 41 | font-size:1.4em; 42 | } 43 | h4 { 44 | font-size:1.3em; 45 | } 46 | h5 { 47 | font-size:1.2em; 48 | } 49 | h6 { 50 | font-size:1.1em; 51 | } 52 | ul { 53 | list-style-type:disc; 54 | } 55 | code, tt { 56 | font-size:1.2em; 57 | } 58 | dt code { 59 | font-size:1.2em; 60 | } 61 | table tr td dt code { 62 | font-size:1.2em; 63 | vertical-align:top; 64 | } 65 | sup { 66 | font-size:.6em; 67 | } 68 | /* 69 | Document title and Copyright styles 70 | */ 71 | .clear { 72 | clear:both; 73 | height:0px; 74 | overflow:hidden; 75 | } 76 | .aboutLanguage { 77 | float:right; 78 | padding:0px 21px; 79 | font-size:.8em; 80 | z-index:200; 81 | margin-top:-7px; 82 | } 83 | .legalCopy { 84 | margin-left:.5em; 85 | } 86 | .bar a, .bar a:link, .bar a:visited, .bar a:active { 87 | color:#FFFFFF; 88 | text-decoration:none; 89 | } 90 | .bar a:hover, .bar a:focus { 91 | color:#bb7a2a; 92 | } 93 | .tab { 94 | background-color:#0066FF; 95 | background-image:url(resources/titlebar.gif); 96 | background-position:left top; 97 | background-repeat:no-repeat; 98 | color:#ffffff; 99 | padding:8px; 100 | width:5em; 101 | font-weight:bold; 102 | } 103 | /* 104 | Navigation bar styles 105 | */ 106 | .bar { 107 | background-image:url(resources/background.gif); 108 | background-repeat:repeat-x; 109 | color:#FFFFFF; 110 | padding:.8em .5em .4em .8em; 111 | height:auto;/*height:1.8em;*/ 112 | font-size:1em; 113 | margin:0; 114 | } 115 | .topNav { 116 | background-image:url(resources/background.gif); 117 | background-repeat:repeat-x; 118 | color:#FFFFFF; 119 | float:left; 120 | padding:0; 121 | width:100%; 122 | clear:right; 123 | height:2.8em; 124 | padding-top:10px; 125 | overflow:hidden; 126 | } 127 | .bottomNav { 128 | margin-top:10px; 129 | background-image:url(resources/background.gif); 130 | background-repeat:repeat-x; 131 | color:#FFFFFF; 132 | float:left; 133 | padding:0; 134 | width:100%; 135 | clear:right; 136 | height:2.8em; 137 | padding-top:10px; 138 | overflow:hidden; 139 | } 140 | .subNav { 141 | background-color:#dee3e9; 142 | border-bottom:1px solid #9eadc0; 143 | float:left; 144 | width:100%; 145 | overflow:hidden; 146 | } 147 | .subNav div { 148 | clear:left; 149 | float:left; 150 | padding:0 0 5px 6px; 151 | } 152 | ul.navList, ul.subNavList { 153 | float:left; 154 | margin:0 25px 0 0; 155 | padding:0; 156 | } 157 | ul.navList li{ 158 | list-style:none; 159 | float:left; 160 | padding:3px 6px; 161 | } 162 | ul.subNavList li{ 163 | list-style:none; 164 | float:left; 165 | font-size:90%; 166 | } 167 | .topNav a:link, .topNav a:active, .topNav a:visited, .bottomNav a:link, .bottomNav a:active, .bottomNav a:visited { 168 | color:#FFFFFF; 169 | text-decoration:none; 170 | } 171 | .topNav a:hover, .bottomNav a:hover { 172 | text-decoration:none; 173 | color:#bb7a2a; 174 | } 175 | .navBarCell1Rev { 176 | background-image:url(resources/tab.gif); 177 | background-color:#a88834; 178 | color:#FFFFFF; 179 | margin: auto 5px; 180 | border:1px solid #c9aa44; 181 | } 182 | /* 183 | Page header and footer styles 184 | */ 185 | .header, .footer { 186 | clear:both; 187 | margin:0 20px; 188 | padding:5px 0 0 0; 189 | } 190 | .indexHeader { 191 | margin:10px; 192 | position:relative; 193 | } 194 | .indexHeader h1 { 195 | font-size:1.3em; 196 | } 197 | .title { 198 | color:#2c4557; 199 | margin:10px 0; 200 | } 201 | .subTitle { 202 | margin:5px 0 0 0; 203 | } 204 | .header ul { 205 | margin:0 0 25px 0; 206 | padding:0; 207 | } 208 | .footer ul { 209 | margin:20px 0 5px 0; 210 | } 211 | .header ul li, .footer ul li { 212 | list-style:none; 213 | font-size:1.2em; 214 | } 215 | /* 216 | Heading styles 217 | */ 218 | div.details ul.blockList ul.blockList ul.blockList li.blockList h4, div.details ul.blockList ul.blockList ul.blockListLast li.blockList h4 { 219 | background-color:#dee3e9; 220 | border-top:1px solid #9eadc0; 221 | border-bottom:1px solid #9eadc0; 222 | margin:0 0 6px -8px; 223 | padding:2px 5px; 224 | } 225 | ul.blockList ul.blockList ul.blockList li.blockList h3 { 226 | background-color:#dee3e9; 227 | border-top:1px solid #9eadc0; 228 | border-bottom:1px solid #9eadc0; 229 | margin:0 0 6px -8px; 230 | padding:2px 5px; 231 | } 232 | ul.blockList ul.blockList li.blockList h3 { 233 | padding:0; 234 | margin:15px 0; 235 | } 236 | ul.blockList li.blockList h2 { 237 | padding:0px 0 20px 0; 238 | } 239 | /* 240 | Page layout container styles 241 | */ 242 | .contentContainer, .sourceContainer, .classUseContainer, .serializedFormContainer, .constantValuesContainer { 243 | clear:both; 244 | padding:10px 20px; 245 | position:relative; 246 | } 247 | .indexContainer { 248 | margin:10px; 249 | position:relative; 250 | font-size:1.0em; 251 | } 252 | .indexContainer h2 { 253 | font-size:1.1em; 254 | padding:0 0 3px 0; 255 | } 256 | .indexContainer ul { 257 | margin:0; 258 | padding:0; 259 | } 260 | .indexContainer ul li { 261 | list-style:none; 262 | } 263 | .contentContainer .description dl dt, .contentContainer .details dl dt, .serializedFormContainer dl dt { 264 | font-size:1.1em; 265 | font-weight:bold; 266 | margin:10px 0 0 0; 267 | color:#4E4E4E; 268 | } 269 | .contentContainer .description dl dd, .contentContainer .details dl dd, .serializedFormContainer dl dd { 270 | margin:10px 0 10px 20px; 271 | } 272 | .serializedFormContainer dl.nameValue dt { 273 | margin-left:1px; 274 | font-size:1.1em; 275 | display:inline; 276 | font-weight:bold; 277 | } 278 | .serializedFormContainer dl.nameValue dd { 279 | margin:0 0 0 1px; 280 | font-size:1.1em; 281 | display:inline; 282 | } 283 | /* 284 | List styles 285 | */ 286 | ul.horizontal li { 287 | display:inline; 288 | font-size:0.9em; 289 | } 290 | ul.inheritance { 291 | margin:0; 292 | padding:0; 293 | } 294 | ul.inheritance li { 295 | display:inline; 296 | list-style:none; 297 | } 298 | ul.inheritance li ul.inheritance { 299 | margin-left:15px; 300 | padding-left:15px; 301 | padding-top:1px; 302 | } 303 | ul.blockList, ul.blockListLast { 304 | margin:10px 0 10px 0; 305 | padding:0; 306 | } 307 | ul.blockList li.blockList, ul.blockListLast li.blockList { 308 | list-style:none; 309 | margin-bottom:25px; 310 | } 311 | ul.blockList ul.blockList li.blockList, ul.blockList ul.blockListLast li.blockList { 312 | padding:0px 20px 5px 10px; 313 | border:1px solid #9eadc0; 314 | background-color:#f9f9f9; 315 | } 316 | ul.blockList ul.blockList ul.blockList li.blockList, ul.blockList ul.blockList ul.blockListLast li.blockList { 317 | padding:0 0 5px 8px; 318 | background-color:#ffffff; 319 | border:1px solid #9eadc0; 320 | border-top:none; 321 | } 322 | ul.blockList ul.blockList ul.blockList ul.blockList li.blockList { 323 | margin-left:0; 324 | padding-left:0; 325 | padding-bottom:15px; 326 | border:none; 327 | border-bottom:1px solid #9eadc0; 328 | } 329 | ul.blockList ul.blockList ul.blockList ul.blockList li.blockListLast { 330 | list-style:none; 331 | border-bottom:none; 332 | padding-bottom:0; 333 | } 334 | table tr td dl, table tr td dl dt, table tr td dl dd { 335 | margin-top:0; 336 | margin-bottom:1px; 337 | } 338 | /* 339 | Table styles 340 | */ 341 | .contentContainer table, .classUseContainer table, .constantValuesContainer table { 342 | border-bottom:1px solid #9eadc0; 343 | width:100%; 344 | } 345 | .contentContainer ul li table, .classUseContainer ul li table, .constantValuesContainer ul li table { 346 | width:100%; 347 | } 348 | .contentContainer .description table, .contentContainer .details table { 349 | border-bottom:none; 350 | } 351 | .contentContainer ul li table th.colOne, .contentContainer ul li table th.colFirst, .contentContainer ul li table th.colLast, .classUseContainer ul li table th, .constantValuesContainer ul li table th, .contentContainer ul li table td.colOne, .contentContainer ul li table td.colFirst, .contentContainer ul li table td.colLast, .classUseContainer ul li table td, .constantValuesContainer ul li table td{ 352 | vertical-align:top; 353 | padding-right:20px; 354 | } 355 | .contentContainer ul li table th.colLast, .classUseContainer ul li table th.colLast,.constantValuesContainer ul li table th.colLast, 356 | .contentContainer ul li table td.colLast, .classUseContainer ul li table td.colLast,.constantValuesContainer ul li table td.colLast, 357 | .contentContainer ul li table th.colOne, .classUseContainer ul li table th.colOne, 358 | .contentContainer ul li table td.colOne, .classUseContainer ul li table td.colOne { 359 | padding-right:3px; 360 | } 361 | .overviewSummary caption, .packageSummary caption, .contentContainer ul.blockList li.blockList caption, .summary caption, .classUseContainer caption, .constantValuesContainer caption { 362 | position:relative; 363 | text-align:left; 364 | background-repeat:no-repeat; 365 | color:#FFFFFF; 366 | font-weight:bold; 367 | clear:none; 368 | overflow:hidden; 369 | padding:0px; 370 | margin:0px; 371 | } 372 | caption a:link, caption a:hover, caption a:active, caption a:visited { 373 | color:#FFFFFF; 374 | } 375 | .overviewSummary caption span, .packageSummary caption span, .contentContainer ul.blockList li.blockList caption span, .summary caption span, .classUseContainer caption span, .constantValuesContainer caption span { 376 | white-space:nowrap; 377 | padding-top:8px; 378 | padding-left:8px; 379 | display:block; 380 | float:left; 381 | background-image:url(resources/titlebar.gif); 382 | height:18px; 383 | } 384 | .overviewSummary .tabEnd, .packageSummary .tabEnd, .contentContainer ul.blockList li.blockList .tabEnd, .summary .tabEnd, .classUseContainer .tabEnd, .constantValuesContainer .tabEnd { 385 | width:10px; 386 | background-image:url(resources/titlebar_end.gif); 387 | background-repeat:no-repeat; 388 | background-position:top right; 389 | position:relative; 390 | float:left; 391 | } 392 | ul.blockList ul.blockList li.blockList table { 393 | margin:0 0 12px 0px; 394 | width:100%; 395 | } 396 | .tableSubHeadingColor { 397 | background-color: #EEEEFF; 398 | } 399 | .altColor { 400 | background-color:#eeeeef; 401 | } 402 | .rowColor { 403 | background-color:#ffffff; 404 | } 405 | .overviewSummary td, .packageSummary td, .contentContainer ul.blockList li.blockList td, .summary td, .classUseContainer td, .constantValuesContainer td { 406 | text-align:left; 407 | padding:3px 3px 3px 7px; 408 | } 409 | th.colFirst, th.colLast, th.colOne, .constantValuesContainer th { 410 | background:#dee3e9; 411 | border-top:1px solid #9eadc0; 412 | border-bottom:1px solid #9eadc0; 413 | text-align:left; 414 | padding:3px 3px 3px 7px; 415 | } 416 | td.colOne a:link, td.colOne a:active, td.colOne a:visited, td.colOne a:hover, td.colFirst a:link, td.colFirst a:active, td.colFirst a:visited, td.colFirst a:hover, td.colLast a:link, td.colLast a:active, td.colLast a:visited, td.colLast a:hover, .constantValuesContainer td a:link, .constantValuesContainer td a:active, .constantValuesContainer td a:visited, .constantValuesContainer td a:hover { 417 | font-weight:bold; 418 | } 419 | td.colFirst, th.colFirst { 420 | border-left:1px solid #9eadc0; 421 | white-space:nowrap; 422 | } 423 | td.colLast, th.colLast { 424 | border-right:1px solid #9eadc0; 425 | } 426 | td.colOne, th.colOne { 427 | border-right:1px solid #9eadc0; 428 | border-left:1px solid #9eadc0; 429 | } 430 | table.overviewSummary { 431 | padding:0px; 432 | margin-left:0px; 433 | } 434 | table.overviewSummary td.colFirst, table.overviewSummary th.colFirst, 435 | table.overviewSummary td.colOne, table.overviewSummary th.colOne { 436 | width:25%; 437 | vertical-align:middle; 438 | } 439 | table.packageSummary td.colFirst, table.overviewSummary th.colFirst { 440 | width:25%; 441 | vertical-align:middle; 442 | } 443 | /* 444 | Content styles 445 | */ 446 | .description pre { 447 | margin-top:0; 448 | } 449 | .deprecatedContent { 450 | margin:0; 451 | padding:10px 0; 452 | } 453 | .docSummary { 454 | padding:0; 455 | } 456 | /* 457 | Formatting effect styles 458 | */ 459 | .sourceLineNo { 460 | color:green; 461 | padding:0 30px 0 0; 462 | } 463 | h1.hidden { 464 | visibility:hidden; 465 | overflow:hidden; 466 | font-size:.9em; 467 | } 468 | .block { 469 | display:block; 470 | margin:3px 0 0 0; 471 | } 472 | .strong { 473 | font-weight:bold; 474 | } 475 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alibaba/AndFix/0351a4bc38a7d30bc61a6d3e74777d4eff4ad5e9/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Tue Sep 15 17:37:25 CST 2015 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.6-bin.zip 7 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 10 | DEFAULT_JVM_OPTS="" 11 | 12 | APP_NAME="Gradle" 13 | APP_BASE_NAME=`basename "$0"` 14 | 15 | # Use the maximum available, or set MAX_FD != -1 to use that value. 16 | MAX_FD="maximum" 17 | 18 | warn ( ) { 19 | echo "$*" 20 | } 21 | 22 | die ( ) { 23 | echo 24 | echo "$*" 25 | echo 26 | exit 1 27 | } 28 | 29 | # OS specific support (must be 'true' or 'false'). 30 | cygwin=false 31 | msys=false 32 | darwin=false 33 | case "`uname`" in 34 | CYGWIN* ) 35 | cygwin=true 36 | ;; 37 | Darwin* ) 38 | darwin=true 39 | ;; 40 | MINGW* ) 41 | msys=true 42 | ;; 43 | esac 44 | 45 | # For Cygwin, ensure paths are in UNIX format before anything is touched. 46 | if $cygwin ; then 47 | [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` 48 | fi 49 | 50 | # Attempt to set APP_HOME 51 | # Resolve links: $0 may be a link 52 | PRG="$0" 53 | # Need this for relative symlinks. 54 | while [ -h "$PRG" ] ; do 55 | ls=`ls -ld "$PRG"` 56 | link=`expr "$ls" : '.*-> \(.*\)$'` 57 | if expr "$link" : '/.*' > /dev/null; then 58 | PRG="$link" 59 | else 60 | PRG=`dirname "$PRG"`"/$link" 61 | fi 62 | done 63 | SAVED="`pwd`" 64 | cd "`dirname \"$PRG\"`/" >&- 65 | APP_HOME="`pwd -P`" 66 | cd "$SAVED" >&- 67 | 68 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 69 | 70 | # Determine the Java command to use to start the JVM. 71 | if [ -n "$JAVA_HOME" ] ; then 72 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 73 | # IBM's JDK on AIX uses strange locations for the executables 74 | JAVACMD="$JAVA_HOME/jre/sh/java" 75 | else 76 | JAVACMD="$JAVA_HOME/bin/java" 77 | fi 78 | if [ ! -x "$JAVACMD" ] ; then 79 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 80 | 81 | Please set the JAVA_HOME variable in your environment to match the 82 | location of your Java installation." 83 | fi 84 | else 85 | JAVACMD="java" 86 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 87 | 88 | Please set the JAVA_HOME variable in your environment to match the 89 | location of your Java installation." 90 | fi 91 | 92 | # Increase the maximum file descriptors if we can. 93 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then 94 | MAX_FD_LIMIT=`ulimit -H -n` 95 | if [ $? -eq 0 ] ; then 96 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 97 | MAX_FD="$MAX_FD_LIMIT" 98 | fi 99 | ulimit -n $MAX_FD 100 | if [ $? -ne 0 ] ; then 101 | warn "Could not set maximum file descriptor limit: $MAX_FD" 102 | fi 103 | else 104 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 105 | fi 106 | fi 107 | 108 | # For Darwin, add options to specify how the application appears in the dock 109 | if $darwin; then 110 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 111 | fi 112 | 113 | # For Cygwin, switch paths to Windows format before running java 114 | if $cygwin ; then 115 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 116 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules 158 | function splitJvmOpts() { 159 | JVM_OPTS=("$@") 160 | } 161 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS 162 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" 163 | 164 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" 165 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 12 | set DEFAULT_JVM_OPTS= 13 | 14 | set DIRNAME=%~dp0 15 | if "%DIRNAME%" == "" set DIRNAME=. 16 | set APP_BASE_NAME=%~n0 17 | set APP_HOME=%DIRNAME% 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windowz variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /images/license.svg: -------------------------------------------------------------------------------- 1 | licenselicenseApache 2.0Apache 2.0 -------------------------------------------------------------------------------- /images/principle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alibaba/AndFix/0351a4bc38a7d30bc61a6d3e74777d4eff4ad5e9/images/principle.png -------------------------------------------------------------------------------- /images/process.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alibaba/AndFix/0351a4bc38a7d30bc61a6d3e74777d4eff4ad5e9/images/process.png -------------------------------------------------------------------------------- /jni/Android.mk: -------------------------------------------------------------------------------- 1 | 2 | 3 | LOCAL_PATH:= $(call my-dir) 4 | include $(CLEAR_VARS) 5 | 6 | LOCAL_SRC_FILES:= andfix.cpp\ 7 | art/art_method_replace.cpp \ 8 | art/art_method_replace_4_4.cpp \ 9 | art/art_method_replace_5_0.cpp \ 10 | art/art_method_replace_5_1.cpp \ 11 | art/art_method_replace_6_0.cpp \ 12 | art/art_method_replace_7_0.cpp \ 13 | dalvik/dalvik_method_replace.cpp \ 14 | 15 | LOCAL_CFLAGS := -std=gnu++11 -fpermissive -DDEBUG -O0 16 | 17 | LOCAL_C_INCLUDES := 18 | 19 | LOCAL_SHARED_LIBRARIES := 20 | 21 | LOCAL_LDLIBS := -llog 22 | 23 | LOCAL_STATIC_LIBRARIES := 24 | 25 | LOCAL_MODULE:= andfix 26 | 27 | include $(BUILD_SHARED_LIBRARY) 28 | -------------------------------------------------------------------------------- /jni/Application.mk: -------------------------------------------------------------------------------- 1 | # The ARMv7 is significanly faster due to the use of the hardware FPU 2 | NDK_TOOLCHAIN_VERSION := 4.9 3 | APP_ABI := all 4 | APP_PLATFORM := android-9 5 | APP_STL := gnustl_static -------------------------------------------------------------------------------- /jni/andfix.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright (c) 2015, alipay.com 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | /* 19 | * andfix.cpp 20 | * 21 | * @author : sanping.li@alipay.com 22 | * 23 | */ 24 | #include 25 | #include 26 | #include 27 | 28 | #include "common.h" 29 | 30 | #define JNIREG_CLASS "com/alipay/euler/andfix/AndFix" 31 | 32 | //dalvik 33 | extern jboolean dalvik_setup(JNIEnv* env, int apilevel); 34 | extern void dalvik_replaceMethod(JNIEnv* env, jobject src, jobject dest); 35 | extern void dalvik_setFieldFlag(JNIEnv* env, jobject field); 36 | //art 37 | extern jboolean art_setup(JNIEnv* env, int apilevel); 38 | extern void art_replaceMethod(JNIEnv* env, jobject src, jobject dest); 39 | extern void art_setFieldFlag(JNIEnv* env, jobject field); 40 | 41 | static bool isArt; 42 | 43 | static jboolean setup(JNIEnv* env, jclass clazz, jboolean isart, 44 | jint apilevel) { 45 | isArt = isart; 46 | LOGD("vm is: %s , apilevel is: %i", (isArt ? "art" : "dalvik"), 47 | (int )apilevel); 48 | if (isArt) { 49 | return art_setup(env, (int) apilevel); 50 | } else { 51 | return dalvik_setup(env, (int) apilevel); 52 | } 53 | } 54 | 55 | static void replaceMethod(JNIEnv* env, jclass clazz, jobject src, 56 | jobject dest) { 57 | if (isArt) { 58 | art_replaceMethod(env, src, dest); 59 | } else { 60 | dalvik_replaceMethod(env, src, dest); 61 | } 62 | } 63 | 64 | static void setFieldFlag(JNIEnv* env, jclass clazz, jobject field) { 65 | if (isArt) { 66 | art_setFieldFlag(env, field); 67 | } else { 68 | dalvik_setFieldFlag(env, field); 69 | } 70 | } 71 | /* 72 | * JNI registration. 73 | */ 74 | static JNINativeMethod gMethods[] = { 75 | /* name, signature, funcPtr */ 76 | { "setup", "(ZI)Z", (void*) setup }, { "replaceMethod", 77 | "(Ljava/lang/reflect/Method;Ljava/lang/reflect/Method;)V", 78 | (void*) replaceMethod }, { "setFieldFlag", 79 | "(Ljava/lang/reflect/Field;)V", (void*) setFieldFlag }, }; 80 | 81 | /* 82 | * Register several native methods for one class. 83 | */ 84 | static int registerNativeMethods(JNIEnv* env, const char* className, 85 | JNINativeMethod* gMethods, int numMethods) { 86 | jclass clazz; 87 | clazz = env->FindClass(className); 88 | if (clazz == NULL) { 89 | return JNI_FALSE; 90 | } 91 | if (env->RegisterNatives(clazz, gMethods, numMethods) < 0) { 92 | return JNI_FALSE; 93 | } 94 | 95 | return JNI_TRUE; 96 | } 97 | 98 | /* 99 | * Register native methods for all classes we know about. 100 | */ 101 | static int registerNatives(JNIEnv* env) { 102 | if (!registerNativeMethods(env, JNIREG_CLASS, gMethods, 103 | sizeof(gMethods) / sizeof(gMethods[0]))) 104 | return JNI_FALSE; 105 | 106 | return JNI_TRUE; 107 | } 108 | 109 | /* 110 | * Set some test stuff up. 111 | * 112 | * Returns the JNI version on success, -1 on failure. 113 | */ 114 | JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved) { 115 | JNIEnv* env = NULL; 116 | jint result = -1; 117 | 118 | if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) { 119 | return -1; 120 | } 121 | assert(env != NULL); 122 | 123 | if (!registerNatives(env)) { //注册 124 | return -1; 125 | } 126 | /* success -- return valid version number */ 127 | result = JNI_VERSION_1_4; 128 | 129 | return result; 130 | } 131 | 132 | -------------------------------------------------------------------------------- /jni/art/art.h: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright (c) 2015, alipay.com 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | /** 19 | * art.h 20 | * 21 | * @author : sanping.li@alipay.com 22 | * 23 | */ 24 | 25 | #include 26 | 27 | #ifdef HAVE_STDINT_H 28 | # include /* C99 */ 29 | typedef uint8_t u1; 30 | typedef uint16_t u2; 31 | typedef uint32_t u4; 32 | typedef uint64_t u8; 33 | typedef int8_t s1; 34 | typedef int16_t s2; 35 | typedef int32_t s4; 36 | typedef int64_t s8; 37 | #else 38 | typedef unsigned char u1; 39 | typedef unsigned short u2; 40 | typedef unsigned int u4; 41 | typedef unsigned long long u8; 42 | typedef signed char s1; 43 | typedef signed short s2; 44 | typedef signed int s4; 45 | typedef signed long long s8; 46 | #endif 47 | 48 | void replace_4_4(JNIEnv* env, jobject src, jobject dest); 49 | void setFieldFlag_4_4(JNIEnv* env, jobject field); 50 | void replace_5_0(JNIEnv* env, jobject src, jobject dest); 51 | void setFieldFlag_5_0(JNIEnv* env, jobject field); 52 | void replace_5_1(JNIEnv* env, jobject src, jobject dest); 53 | void setFieldFlag_5_1(JNIEnv* env, jobject field); 54 | void replace_6_0(JNIEnv* env, jobject src, jobject dest); 55 | void setFieldFlag_6_0(JNIEnv* env, jobject field); 56 | void replace_7_0(JNIEnv* env, jobject src, jobject dest); 57 | void setFieldFlag_7_0(JNIEnv* env, jobject field); 58 | 59 | -------------------------------------------------------------------------------- /jni/art/art_4_4.h: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright (c) 2011 The Android Open Source Project 4 | * Copyright (c) 2015, alipay.com 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | /** 20 | * art_4_4.h 21 | * 22 | * @author : sanping.li@alipay.com 23 | * 24 | */ 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | #include /* C99 */ 32 | 33 | namespace art { 34 | namespace mirror { 35 | class Object { 36 | public: 37 | void* klass_; 38 | 39 | uint32_t monitor_; 40 | }; 41 | class Class: public Object { 42 | public: 43 | // defining class loader, or NULL for the "bootstrap" system loader 44 | void* class_loader_; 45 | // For array classes, the component class object for instanceof/checkcast 46 | // (for String[][][], this will be String[][]). NULL for non-array classes. 47 | Class* component_type_; 48 | // DexCache of resolved constant pool entries (will be NULL for classes generated by the 49 | // runtime such as arrays and primitive classes). 50 | void* dex_cache_; 51 | // static, private, and methods 52 | void* direct_methods_; 53 | // instance fields 54 | // 55 | // These describe the layout of the contents of an Object. 56 | // Note that only the fields directly declared by this class are 57 | // listed in ifields; fields declared by a superclass are listed in 58 | // the superclass's Class.ifields. 59 | // 60 | // All instance fields that refer to objects are guaranteed to be at 61 | // the beginning of the field list. num_reference_instance_fields_ 62 | // specifies the number of reference fields. 63 | void* ifields_; 64 | // The interface table (iftable_) contains pairs of a interface class and an array of the 65 | // interface methods. There is one pair per interface supported by this class. That means one 66 | // pair for each interface we support directly, indirectly via superclass, or indirectly via a 67 | // superinterface. This will be null if neither we nor our superclass implement any interfaces. 68 | // 69 | // Why we need this: given "class Foo implements Face", declare "Face faceObj = new Foo()". 70 | // Invoke faceObj.blah(), where "blah" is part of the Face interface. We can't easily use a 71 | // single vtable. 72 | // 73 | // For every interface a concrete class implements, we create an array of the concrete vtable_ 74 | // methods for the methods in the interface. 75 | void* iftable_; 76 | // Descriptor for the class such as "java.lang.Class" or "[C". Lazily initialized by ComputeName 77 | void* name_; 78 | // Static fields 79 | void* sfields_; 80 | // The superclass, or NULL if this is java.lang.Object, an interface or primitive type. 81 | Class* super_class_; 82 | // If class verify fails, we must return same error on subsequent tries. 83 | Class* verify_error_class_; 84 | // Virtual methods defined in this class; invoked through vtable. 85 | void* virtual_methods_; 86 | // Virtual method table (vtable), for use by "invoke-virtual". The vtable from the superclass is 87 | // copied in, and virtual methods from our class either replace those from the super or are 88 | // appended. For abstract classes, methods may be created in the vtable that aren't in 89 | // virtual_ methods_ for miranda methods. 90 | void* vtable_; 91 | // Access flags; low 16 bits are defined by VM spec. 92 | uint32_t access_flags_; 93 | // Total size of the Class instance; used when allocating storage on gc heap. 94 | // See also object_size_. 95 | size_t class_size_; 96 | // Tid used to check for recursive invocation. 97 | pid_t clinit_thread_id_; 98 | // ClassDef index in dex file, -1 if no class definition such as an array. 99 | // TODO: really 16bits 100 | int32_t dex_class_def_idx_; 101 | // Type index in dex file. 102 | // TODO: really 16bits 103 | int32_t dex_type_idx_; 104 | // Number of instance fields that are object refs. 105 | size_t num_reference_instance_fields_; 106 | // Number of static fields that are object refs, 107 | size_t num_reference_static_fields_; 108 | // Total object size; used when allocating storage on gc heap. 109 | // (For interfaces and abstract classes this will be zero.) 110 | // See also class_size_. 111 | size_t object_size_; 112 | // Primitive type value, or Primitive::kPrimNot (0); set for generated primitive classes. 113 | uint32_t primitive_type_; 114 | // Bitmap of offsets of ifields. 115 | uint32_t reference_instance_offsets_; 116 | // Bitmap of offsets of sfields. 117 | uint32_t reference_static_offsets_; 118 | // State of class initialization. 119 | int32_t status_; 120 | // TODO: ? 121 | // initiating class loader list 122 | // NOTE: for classes with low serialNumber, these are unused, and the 123 | // values are kept in a table in gDvm. 124 | // InitiatingLoaderList initiating_loader_list_; 125 | 126 | // Location of first static field. 127 | uint32_t fields_[0]; 128 | // java.lang.Class 129 | static Class* java_lang_Class_; 130 | }; 131 | 132 | class ArtField: public Object { 133 | public: 134 | // Field order required by test "ValidateFieldOrderOfJavaCppUnionClasses". 135 | // The class we are a part of 136 | Class* declaring_class_; 137 | uint32_t access_flags_; 138 | // Dex cache index of field id 139 | uint32_t field_dex_idx_; 140 | // Offset of field within an instance or in the Class' static fields 141 | uint32_t offset_; 142 | static Class* java_lang_reflect_ArtField_; 143 | }; 144 | 145 | class ArtMethod: public Object { 146 | public: 147 | // Field order required by test "ValidateFieldOrderOfJavaCppUnionClasses". 148 | // The class we are a part of 149 | Class* declaring_class_; 150 | // short cuts to declaring_class_->dex_cache_ member for fast compiled code access 151 | void* dex_cache_initialized_static_storage_; 152 | // short cuts to declaring_class_->dex_cache_ member for fast compiled code access 153 | void* dex_cache_resolved_methods_; 154 | // short cuts to declaring_class_->dex_cache_ member for fast compiled code access 155 | void* dex_cache_resolved_types_; 156 | // short cuts to declaring_class_->dex_cache_ member for fast compiled code access 157 | void* dex_cache_strings_; 158 | // Access flags; low 16 bits are defined by spec. 159 | uint32_t access_flags_; 160 | // Offset to the CodeItem. 161 | uint32_t code_item_offset_; 162 | // Architecture-dependent register spill mask 163 | uint32_t core_spill_mask_; 164 | // Compiled code associated with this method for callers from managed code. 165 | // May be compiled managed code or a bridge for invoking a native method. 166 | // TODO: Break apart this into portable and quick. 167 | const void* entry_point_from_compiled_code_; 168 | // Called by the interpreter to execute this method. 169 | void* entry_point_from_interpreter_; 170 | // Architecture-dependent register spill mask 171 | uint32_t fp_spill_mask_; 172 | // Total size in bytes of the frame 173 | size_t frame_size_in_bytes_; 174 | // Garbage collection map of native PC offsets (quick) or dex PCs (portable) to reference bitmaps. 175 | const uint8_t* gc_map_; 176 | // Mapping from native pc to dex pc 177 | const uint32_t* mapping_table_; 178 | // Index into method_ids of the dex file associated with this method 179 | uint32_t method_dex_index_; 180 | // For concrete virtual methods, this is the offset of the method in Class::vtable_. 181 | // 182 | // For abstract methods in an interface class, this is the offset of the method in 183 | // "iftable_->Get(n)->GetMethodArray()". 184 | // 185 | // For static and direct methods this is the index in the direct methods table. 186 | uint32_t method_index_; 187 | // The target native method registered with this method 188 | const void* native_method_; 189 | // When a register is promoted into a register, the spill mask holds which registers hold dex 190 | // registers. The first promoted register's corresponding dex register is vmap_table_[1], the Nth 191 | // is vmap_table_[N]. vmap_table_[0] holds the length of the table. 192 | const uint16_t* vmap_table_; 193 | static Class* java_lang_reflect_ArtMethod_; 194 | }; 195 | 196 | } 197 | 198 | } 199 | -------------------------------------------------------------------------------- /jni/art/art_5_0.h: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright (c) 2011 The Android Open Source Project 4 | * Copyright (c) 2015, alipay.com 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | /** 20 | * art_5_0.h 21 | * 22 | * @author : sanping.li@alipay.com 23 | * 24 | */ 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | #include /* C99 */ 32 | 33 | namespace art { 34 | namespace mirror { 35 | class Object { 36 | public: 37 | uint32_t klass_; 38 | 39 | uint32_t monitor_; 40 | }; 41 | class Class: public Object { 42 | public: 43 | // Interface method table size. Increasing this value reduces the chance of two interface methods 44 | // colliding in the interface method table but increases the size of classes that implement 45 | // (non-marker) interfaces. 46 | static constexpr size_t kImtSize = 64; //IMT_SIZE; 47 | // defining class loader, or NULL for the "bootstrap" system loader 48 | uint32_t class_loader_; 49 | // For array classes, the component class object for instanceof/checkcast 50 | // (for String[][][], this will be String[][]). NULL for non-array classes. 51 | uint32_t component_type_; 52 | // DexCache of resolved constant pool entries (will be NULL for classes generated by the 53 | // runtime such as arrays and primitive classes). 54 | uint32_t dex_cache_; 55 | // static, private, and methods 56 | uint32_t direct_methods_; 57 | // instance fields 58 | // 59 | // These describe the layout of the contents of an Object. 60 | // Note that only the fields directly declared by this class are 61 | // listed in ifields; fields declared by a superclass are listed in 62 | // the superclass's Class.ifields. 63 | // 64 | // All instance fields that refer to objects are guaranteed to be at 65 | // the beginning of the field list. num_reference_instance_fields_ 66 | // specifies the number of reference fields. 67 | uint32_t ifields_; 68 | // The interface table (iftable_) contains pairs of a interface class and an array of the 69 | // interface methods. There is one pair per interface supported by this class. That means one 70 | // pair for each interface we support directly, indirectly via superclass, or indirectly via a 71 | // superinterface. This will be null if neither we nor our superclass implement any interfaces. 72 | // 73 | // Why we need this: given "class Foo implements Face", declare "Face faceObj = new Foo()". 74 | // Invoke faceObj.blah(), where "blah" is part of the Face interface. We can't easily use a 75 | // single vtable. 76 | // 77 | // For every interface a concrete class implements, we create an array of the concrete vtable_ 78 | // methods for the methods in the interface. 79 | uint32_t iftable_; 80 | // Interface method table (imt), for quick "invoke-interface". 81 | uint32_t imtable_; 82 | // Descriptor for the class such as "java.lang.Class" or "[C". Lazily initialized by ComputeName 83 | uint32_t name_; 84 | // Static fields 85 | uint32_t sfields_; 86 | // The superclass, or NULL if this is java.lang.Object, an interface or primitive type. 87 | uint32_t super_class_; 88 | // If class verify fails, we must return same error on subsequent tries. 89 | uint32_t verify_error_class_; 90 | // Virtual methods defined in this class; invoked through vtable. 91 | uint32_t virtual_methods_; 92 | // Virtual method table (vtable), for use by "invoke-virtual". The vtable from the superclass is 93 | // copied in, and virtual methods from our class either replace those from the super or are 94 | // appended. For abstract classes, methods may be created in the vtable that aren't in 95 | // virtual_ methods_ for miranda methods. 96 | uint32_t vtable_; 97 | // Access flags; low 16 bits are defined by VM spec. 98 | uint32_t access_flags_; 99 | // Total size of the Class instance; used when allocating storage on gc heap. 100 | // See also object_size_. 101 | uint32_t class_size_; 102 | // Tid used to check for recursive invocation. 103 | pid_t clinit_thread_id_; 104 | // ClassDef index in dex file, -1 if no class definition such as an array. 105 | // TODO: really 16bits 106 | int32_t dex_class_def_idx_; 107 | // Type index in dex file. 108 | // TODO: really 16bits 109 | int32_t dex_type_idx_; 110 | // Number of instance fields that are object refs. 111 | uint32_t num_reference_instance_fields_; 112 | // Number of static fields that are object refs, 113 | uint32_t num_reference_static_fields_; 114 | // Total object size; used when allocating storage on gc heap. 115 | // (For interfaces and abstract classes this will be zero.) 116 | // See also class_size_. 117 | uint32_t object_size_; 118 | // Primitive type value, or Primitive::kPrimNot (0); set for generated primitive classes. 119 | uint32_t primitive_type_; 120 | // Bitmap of offsets of ifields. 121 | uint32_t reference_instance_offsets_; 122 | // Bitmap of offsets of sfields. 123 | uint32_t reference_static_offsets_; 124 | // State of class initialization. 125 | int32_t status_; 126 | // TODO: ? 127 | // initiating class loader list 128 | // NOTE: for classes with low serialNumber, these are unused, and the 129 | // values are kept in a table in gDvm. 130 | // InitiatingLoaderList initiating_loader_list_; 131 | // The following data exist in real class objects. 132 | // Embedded Imtable, for class object that's not an interface, fixed size. 133 | uint32_t embedded_imtable_[0]; 134 | // Embedded Vtable, for class object that's not an interface, variable size. 135 | uint32_t embedded_vtable_[0]; 136 | // Static fields, variable size. 137 | uint32_t fields_[0]; 138 | // java.lang.Class 139 | static void* java_lang_Class_; 140 | }; 141 | 142 | class ArtField: public Object { 143 | public: 144 | uint32_t declaring_class_; 145 | uint32_t access_flags_; 146 | uint32_t field_dex_idx_; 147 | uint32_t offset_; 148 | }; 149 | 150 | class ArtMethod: public Object { 151 | public: 152 | // Field order required by test "ValidateFieldOrderOfJavaCppUnionClasses". 153 | // The class we are a part of 154 | uint32_t declaring_class_; 155 | 156 | // short cuts to declaring_class_->dex_cache_ member for fast compiled code access 157 | uint32_t dex_cache_resolved_methods_; 158 | 159 | // short cuts to declaring_class_->dex_cache_ member for fast compiled code access 160 | uint32_t dex_cache_resolved_types_; 161 | 162 | // short cuts to declaring_class_->dex_cache_ member for fast compiled code access 163 | uint32_t dex_cache_strings_; 164 | 165 | // Method dispatch from the interpreter invokes this pointer which may cause a bridge into 166 | // compiled code. 167 | uint64_t entry_point_from_interpreter_; 168 | 169 | // Pointer to JNI function registered to this method, or a function to resolve the JNI function. 170 | uint64_t entry_point_from_jni_; 171 | 172 | // Method dispatch from portable compiled code invokes this pointer which may cause bridging into 173 | // quick compiled code or the interpreter. 174 | #if defined(ART_USE_PORTABLE_COMPILER) 175 | uint64_t entry_point_from_portable_compiled_code_; 176 | #endif 177 | 178 | // Method dispatch from quick compiled code invokes this pointer which may cause bridging into 179 | // portable compiled code or the interpreter. 180 | uint64_t entry_point_from_quick_compiled_code_; 181 | 182 | // Pointer to a data structure created by the compiler and used by the garbage collector to 183 | // determine which registers hold live references to objects within the heap. Keyed by native PC 184 | // offsets for the quick compiler and dex PCs for the portable. 185 | uint64_t gc_map_; 186 | 187 | // Access flags; low 16 bits are defined by spec. 188 | uint32_t access_flags_; 189 | 190 | /* Dex file fields. The defining dex file is available via declaring_class_->dex_cache_ */ 191 | 192 | // Offset to the CodeItem. 193 | uint32_t dex_code_item_offset_; 194 | 195 | // Index into method_ids of the dex file associated with this method. 196 | uint32_t dex_method_index_; 197 | 198 | /* End of dex file fields. */ 199 | 200 | // Entry within a dispatch table for this method. For static/direct methods the index is into 201 | // the declaringClass.directMethods, for virtual methods the vtable and for interface methods the 202 | // ifTable. 203 | uint32_t method_index_; 204 | 205 | static void* java_lang_reflect_ArtMethod_; 206 | }; 207 | 208 | } 209 | 210 | } 211 | -------------------------------------------------------------------------------- /jni/art/art_5_1.h: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright (c) 2011 The Android Open Source Project 4 | * Copyright (c) 2015, alipay.com 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | /** 20 | * art_5_1.h 21 | * 22 | * @author : sanping.li@alipay.com 23 | * 24 | */ 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | #include /* C99 */ 32 | 33 | namespace art { 34 | namespace mirror { 35 | class Object { 36 | public: 37 | // The number of vtable entries in java.lang.Object. 38 | static constexpr size_t kVTableLength = 11; 39 | static uint32_t hash_code_seed; 40 | uint32_t klass_; 41 | 42 | uint32_t monitor_; 43 | }; 44 | class Class: public Object { 45 | public: 46 | // Interface method table size. Increasing this value reduces the chance of two interface methods 47 | // colliding in the interface method table but increases the size of classes that implement 48 | // (non-marker) interfaces. 49 | static constexpr size_t kImtSize = 64; //IMT_SIZE; 50 | // defining class loader, or NULL for the "bootstrap" system loader 51 | uint32_t class_loader_; 52 | // For array classes, the component class object for instanceof/checkcast 53 | // (for String[][][], this will be String[][]). NULL for non-array classes. 54 | uint32_t component_type_; 55 | // DexCache of resolved constant pool entries (will be NULL for classes generated by the 56 | // runtime such as arrays and primitive classes). 57 | uint32_t dex_cache_; 58 | // Short cuts to dex_cache_ member for fast compiled code access. 59 | uint32_t dex_cache_strings_; 60 | // static, private, and methods 61 | uint32_t direct_methods_; 62 | // instance fields 63 | // 64 | // These describe the layout of the contents of an Object. 65 | // Note that only the fields directly declared by this class are 66 | // listed in ifields; fields declared by a superclass are listed in 67 | // the superclass's Class.ifields. 68 | // 69 | // All instance fields that refer to objects are guaranteed to be at 70 | // the beginning of the field list. num_reference_instance_fields_ 71 | // specifies the number of reference fields. 72 | uint32_t ifields_; 73 | // The interface table (iftable_) contains pairs of a interface class and an array of the 74 | // interface methods. There is one pair per interface supported by this class. That means one 75 | // pair for each interface we support directly, indirectly via superclass, or indirectly via a 76 | // superinterface. This will be null if neither we nor our superclass implement any interfaces. 77 | // 78 | // Why we need this: given "class Foo implements Face", declare "Face faceObj = new Foo()". 79 | // Invoke faceObj.blah(), where "blah" is part of the Face interface. We can't easily use a 80 | // single vtable. 81 | // 82 | // For every interface a concrete class implements, we create an array of the concrete vtable_ 83 | // methods for the methods in the interface. 84 | uint32_t iftable_; 85 | // Descriptor for the class such as "java.lang.Class" or "[C". Lazily initialized by ComputeName 86 | uint32_t name_; 87 | // Static fields 88 | uint32_t sfields_; 89 | // The superclass, or NULL if this is java.lang.Object, an interface or primitive type. 90 | uint32_t super_class_; 91 | // If class verify fails, we must return same error on subsequent tries. 92 | uint32_t verify_error_class_; 93 | // Virtual methods defined in this class; invoked through vtable. 94 | uint32_t virtual_methods_; 95 | // Virtual method table (vtable), for use by "invoke-virtual". The vtable from the superclass is 96 | // copied in, and virtual methods from our class either replace those from the super or are 97 | // appended. For abstract classes, methods may be created in the vtable that aren't in 98 | // virtual_ methods_ for miranda methods. 99 | uint32_t vtable_; 100 | // Access flags; low 16 bits are defined by VM spec. 101 | uint32_t access_flags_; 102 | // Total size of the Class instance; used when allocating storage on gc heap. 103 | // See also object_size_. 104 | uint32_t class_size_; 105 | // Tid used to check for recursive invocation. 106 | pid_t clinit_thread_id_; 107 | // ClassDef index in dex file, -1 if no class definition such as an array. 108 | // TODO: really 16bits 109 | int32_t dex_class_def_idx_; 110 | // Type index in dex file. 111 | // TODO: really 16bits 112 | int32_t dex_type_idx_; 113 | // Number of instance fields that are object refs. 114 | uint32_t num_reference_instance_fields_; 115 | // Number of static fields that are object refs, 116 | uint32_t num_reference_static_fields_; 117 | // Total object size; used when allocating storage on gc heap. 118 | // (For interfaces and abstract classes this will be zero.) 119 | // See also class_size_. 120 | uint32_t object_size_; 121 | // Primitive type value, or Primitive::kPrimNot (0); set for generated primitive classes. 122 | uint32_t primitive_type_; 123 | // Bitmap of offsets of ifields. 124 | uint32_t reference_instance_offsets_; 125 | // Bitmap of offsets of sfields. 126 | uint32_t reference_static_offsets_; 127 | // State of class initialization. 128 | int32_t status_; 129 | // TODO: ? 130 | // initiating class loader list 131 | // NOTE: for classes with low serialNumber, these are unused, and the 132 | // values are kept in a table in gDvm. 133 | // InitiatingLoaderList initiating_loader_list_; 134 | // The following data exist in real class objects. 135 | // Embedded Imtable, for class object that's not an interface, fixed size. 136 | // ImTableEntry embedded_imtable_[0]; 137 | // Embedded Vtable, for class object that's not an interface, variable size. 138 | // VTableEntry embedded_vtable_[0]; 139 | // Static fields, variable size. 140 | // uint32_t fields_[0]; 141 | // java.lang.Class 142 | static void* java_lang_Class_; 143 | }; 144 | 145 | class ArtField : public Object{ 146 | public: 147 | uint32_t declaring_class_; 148 | int32_t access_flags_; 149 | int32_t field_dex_idx_; 150 | int32_t offset_; 151 | }; 152 | 153 | class ArtMethod: public Object { 154 | public: 155 | // Field order required by test "ValidateFieldOrderOfJavaCppUnionClasses". 156 | // The class we are a part of. 157 | uint32_t declaring_class_; 158 | // Short cuts to declaring_class_->dex_cache_ member for fast compiled code access. 159 | uint32_t dex_cache_resolved_methods_; 160 | // Short cuts to declaring_class_->dex_cache_ member for fast compiled code access. 161 | uint32_t dex_cache_resolved_types_; 162 | // Access flags; low 16 bits are defined by spec. 163 | uint32_t access_flags_; 164 | /* Dex file fields. The defining dex file is available via declaring_class_->dex_cache_ */ 165 | // Offset to the CodeItem. 166 | uint32_t dex_code_item_offset_; 167 | // Index into method_ids of the dex file associated with this method. 168 | uint32_t dex_method_index_; 169 | /* End of dex file fields. */ 170 | // Entry within a dispatch table for this method. For static/direct methods the index is into 171 | // the declaringClass.directMethods, for virtual methods the vtable and for interface methods the 172 | // ifTable. 173 | uint32_t method_index_; 174 | // Fake padding field gets inserted here. 175 | // Must be the last fields in the method. 176 | struct PtrSizedFields { 177 | // Method dispatch from the interpreter invokes this pointer which may cause a bridge into 178 | // compiled code. 179 | void* entry_point_from_interpreter_; 180 | // Pointer to JNI function registered to this method, or a function to resolve the JNI function. 181 | void* entry_point_from_jni_; 182 | // Method dispatch from quick compiled code invokes this pointer which may cause bridging into 183 | // portable compiled code or the interpreter. 184 | void* entry_point_from_quick_compiled_code_; 185 | } ptr_sized_fields_; 186 | static void* java_lang_reflect_ArtMethod_; 187 | }; 188 | 189 | } 190 | 191 | } 192 | -------------------------------------------------------------------------------- /jni/art/art_6_0.h: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright (c) 2011 The Android Open Source Project 4 | * Copyright (c) 2015, alipay.com 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | /** 20 | * art_6_0.h 21 | * 22 | * @author : sanping.li@alipay.com 23 | * 24 | */ 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | #include /* C99 */ 32 | 33 | namespace art { 34 | namespace mirror { 35 | class Object { 36 | public: 37 | // The number of vtable entries in java.lang.Object. 38 | static constexpr size_t kVTableLength = 11; 39 | static uint32_t hash_code_seed; 40 | uint32_t klass_; 41 | 42 | uint32_t monitor_; 43 | }; 44 | class Class: public Object { 45 | public: 46 | // A magic value for reference_instance_offsets_. Ignore the bits and walk the super chain when 47 | // this is the value. 48 | // [This is an unlikely "natural" value, since it would be 30 non-ref instance fields followed by 49 | // 2 ref instance fields.] 50 | static constexpr uint32_t kClassWalkSuper = 0xC0000000; 51 | // Interface method table size. Increasing this value reduces the chance of two interface methods 52 | // colliding in the interface method table but increases the size of classes that implement 53 | // (non-marker) interfaces. 54 | static constexpr size_t kImtSize = 0; //IMT_SIZE; 55 | // Defining class loader, or null for the "bootstrap" system loader. 56 | uint32_t class_loader_; 57 | // For array classes, the component class object for instanceof/checkcast 58 | // (for String[][][], this will be String[][]). null for non-array classes. 59 | uint32_t component_type_; 60 | // DexCache of resolved constant pool entries (will be null for classes generated by the 61 | // runtime such as arrays and primitive classes). 62 | uint32_t dex_cache_; 63 | // Short cuts to dex_cache_ member for fast compiled code access. 64 | uint32_t dex_cache_strings_; 65 | // The interface table (iftable_) contains pairs of a interface class and an array of the 66 | // interface methods. There is one pair per interface supported by this class. That means one 67 | // pair for each interface we support directly, indirectly via superclass, or indirectly via a 68 | // superinterface. This will be null if neither we nor our superclass implement any interfaces. 69 | // 70 | // Why we need this: given "class Foo implements Face", declare "Face faceObj = new Foo()". 71 | // Invoke faceObj.blah(), where "blah" is part of the Face interface. We can't easily use a 72 | // single vtable. 73 | // 74 | // For every interface a concrete class implements, we create an array of the concrete vtable_ 75 | // methods for the methods in the interface. 76 | uint32_t iftable_; 77 | // Descriptor for the class such as "java.lang.Class" or "[C". Lazily initialized by ComputeName 78 | uint32_t name_; 79 | // The superclass, or null if this is java.lang.Object or a primitive type. 80 | // 81 | // Note that interfaces have java.lang.Object as their 82 | // superclass. This doesn't match the expectations in JNI 83 | // GetSuperClass or java.lang.Class.getSuperClass() which need to 84 | // check for interfaces and return null. 85 | uint32_t super_class_; 86 | // If class verify fails, we must return same error on subsequent tries. 87 | uint32_t verify_error_class_; 88 | // Virtual method table (vtable), for use by "invoke-virtual". The vtable from the superclass is 89 | // copied in, and virtual methods from our class either replace those from the super or are 90 | // appended. For abstract classes, methods may be created in the vtable that aren't in 91 | // virtual_ methods_ for miranda methods. 92 | uint32_t vtable_; 93 | // Access flags; low 16 bits are defined by VM spec. 94 | // Note: Shuffled back. 95 | uint32_t access_flags_; 96 | // static, private, and methods. Pointer to an ArtMethod length-prefixed array. 97 | uint64_t direct_methods_; 98 | // instance fields 99 | // 100 | // These describe the layout of the contents of an Object. 101 | // Note that only the fields directly declared by this class are 102 | // listed in ifields; fields declared by a superclass are listed in 103 | // the superclass's Class.ifields. 104 | // 105 | // ArtFields are allocated as a length prefixed ArtField array, and not an array of pointers to 106 | // ArtFields. 107 | uint64_t ifields_; 108 | // Static fields length-prefixed array. 109 | uint64_t sfields_; 110 | // Virtual methods defined in this class; invoked through vtable. Pointer to an ArtMethod 111 | // length-prefixed array. 112 | uint64_t virtual_methods_; 113 | // Total size of the Class instance; used when allocating storage on gc heap. 114 | // See also object_size_. 115 | uint32_t class_size_; 116 | // Tid used to check for recursive invocation. 117 | pid_t clinit_thread_id_; 118 | // ClassDef index in dex file, -1 if no class definition such as an array. 119 | // TODO: really 16bits 120 | int32_t dex_class_def_idx_; 121 | // Type index in dex file. 122 | // TODO: really 16bits 123 | int32_t dex_type_idx_; 124 | // Number of direct fields. 125 | uint32_t num_direct_methods_; 126 | // Number of instance fields. 127 | uint32_t num_instance_fields_; 128 | // Number of instance fields that are object refs. 129 | uint32_t num_reference_instance_fields_; 130 | // Number of static fields that are object refs, 131 | uint32_t num_reference_static_fields_; 132 | // Number of static fields. 133 | uint32_t num_static_fields_; 134 | // Number of virtual methods. 135 | uint32_t num_virtual_methods_; 136 | // Total object size; used when allocating storage on gc heap. 137 | // (For interfaces and abstract classes this will be zero.) 138 | // See also class_size_. 139 | uint32_t object_size_; 140 | // The lower 16 bits contains a Primitive::Type value. The upper 16 141 | // bits contains the size shift of the primitive type. 142 | uint32_t primitive_type_; 143 | // Bitmap of offsets of ifields. 144 | uint32_t reference_instance_offsets_; 145 | // State of class initialization. 146 | uint32_t status_; 147 | // TODO: ? 148 | // initiating class loader list 149 | // NOTE: for classes with low serialNumber, these are unused, and the 150 | // values are kept in a table in gDvm. 151 | // InitiatingLoaderList initiating_loader_list_; 152 | // The following data exist in real class objects. 153 | // Embedded Imtable, for class object that's not an interface, fixed size. 154 | // ImTableEntry embedded_imtable_[0]; 155 | // Embedded Vtable, for class object that's not an interface, variable size. 156 | // VTableEntry embedded_vtable_[0]; 157 | // Static fields, variable size. 158 | // uint32_t fields_[0]; 159 | // java.lang.Class 160 | static uint32_t java_lang_Class_; 161 | }; 162 | 163 | class ArtField { 164 | public: 165 | uint32_t declaring_class_; 166 | uint32_t access_flags_; 167 | uint32_t field_dex_idx_; 168 | uint32_t offset_; 169 | }; 170 | 171 | class ArtMethod { 172 | public: 173 | 174 | // Field order required by test "ValidateFieldOrderOfJavaCppUnionClasses". 175 | // The class we are a part of. 176 | uint32_t declaring_class_; 177 | // Short cuts to declaring_class_->dex_cache_ member for fast compiled code access. 178 | uint32_t dex_cache_resolved_methods_; 179 | // Short cuts to declaring_class_->dex_cache_ member for fast compiled code access. 180 | uint32_t dex_cache_resolved_types_; 181 | // Access flags; low 16 bits are defined by spec. 182 | uint32_t access_flags_; 183 | /* Dex file fields. The defining dex file is available via declaring_class_->dex_cache_ */ 184 | // Offset to the CodeItem. 185 | uint32_t dex_code_item_offset_; 186 | // Index into method_ids of the dex file associated with this method. 187 | uint32_t dex_method_index_; 188 | /* End of dex file fields. */ 189 | // Entry within a dispatch table for this method. For static/direct methods the index is into 190 | // the declaringClass.directMethods, for virtual methods the vtable and for interface methods the 191 | // ifTable. 192 | uint32_t method_index_; 193 | // Fake padding field gets inserted here. 194 | // Must be the last fields in the method. 195 | // PACKED(4) is necessary for the correctness of 196 | // RoundUp(OFFSETOF_MEMBER(ArtMethod, ptr_sized_fields_), pointer_size). 197 | struct PtrSizedFields { 198 | // Method dispatch from the interpreter invokes this pointer which may cause a bridge into 199 | // compiled code. 200 | void* entry_point_from_interpreter_; 201 | // Pointer to JNI function registered to this method, or a function to resolve the JNI function. 202 | void* entry_point_from_jni_; 203 | // Method dispatch from quick compiled code invokes this pointer which may cause bridging into 204 | // the interpreter. 205 | void* entry_point_from_quick_compiled_code_; 206 | } ptr_sized_fields_; 207 | }; 208 | 209 | } 210 | 211 | } 212 | -------------------------------------------------------------------------------- /jni/art/art_7_0.h: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright (c) 2011 The Android Open Source Project 4 | * Copyright (c) 2016, alipay.com 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | /** 20 | * art_7_0.h 21 | * 22 | * @author : sanping.li@alipay.com 23 | * 24 | */ 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | 32 | #include 33 | #include 34 | 35 | #include /* C99 */ 36 | 37 | namespace art { 38 | namespace mirror { 39 | class Object { 40 | public: 41 | // The number of vtable entries in java.lang.Object. 42 | static constexpr size_t kVTableLength = 11; 43 | static uint32_t hash_code_seed; 44 | uint32_t klass_; 45 | 46 | uint32_t monitor_; 47 | }; 48 | 49 | class Class: public Object { 50 | public: 51 | enum Status { 52 | kStatusRetired = -2, // Retired, should not be used. Use the newly cloned one instead. 53 | kStatusError = -1, 54 | kStatusNotReady = 0, 55 | kStatusIdx = 1, // Loaded, DEX idx in super_class_type_idx_ and interfaces_type_idx_. 56 | kStatusLoaded = 2, // DEX idx values resolved. 57 | kStatusResolving = 3, // Just cloned from temporary class object. 58 | kStatusResolved = 4, // Part of linking. 59 | kStatusVerifying = 5, // In the process of being verified. 60 | kStatusRetryVerificationAtRuntime = 6, // Compile time verification failed, retry at runtime. 61 | kStatusVerifyingAtRuntime = 7, // Retrying verification at runtime. 62 | kStatusVerified = 8, // Logically part of linking; done pre-init. 63 | kStatusInitializing = 9, // Class init in progress. 64 | kStatusInitialized = 10, // Ready to go. 65 | kStatusMax = 11, 66 | }; 67 | 68 | // A magic value for reference_instance_offsets_. Ignore the bits and walk the super chain when 69 | // this is the value. 70 | // [This is an unlikely "natural" value, since it would be 30 non-ref instance fields followed by 71 | // 2 ref instance fields.] 72 | static constexpr uint32_t kClassWalkSuper = 0xC0000000; 73 | // Interface method table size. Increasing this value reduces the chance of two interface methods 74 | // colliding in the interface method table but increases the size of classes that implement 75 | // (non-marker) interfaces. 76 | static constexpr size_t kImtSize = 0; //IMT_SIZE; 77 | // 'Class' Object Fields 78 | // Order governed by java field ordering. See art::ClassLinker::LinkFields. 79 | uint32_t annotation_type_; 80 | 81 | // Defining class loader, or null for the "bootstrap" system loader. 82 | uint32_t class_loader_; 83 | // For array classes, the component class object for instanceof/checkcast 84 | // (for String[][][], this will be String[][]). null for non-array classes. 85 | uint32_t component_type_; 86 | // DexCache of resolved constant pool entries (will be null for classes generated by the 87 | // runtime such as arrays and primitive classes). 88 | uint32_t dex_cache_; 89 | // The interface table (iftable_) contains pairs of a interface class and an array of the 90 | // interface methods. There is one pair per interface supported by this class. That means one 91 | // pair for each interface we support directly, indirectly via superclass, or indirectly via a 92 | // superinterface. This will be null if neither we nor our superclass implement any interfaces. 93 | // 94 | // Why we need this: given "class Foo implements Face", declare "Face faceObj = new Foo()". 95 | // Invoke faceObj.blah(), where "blah" is part of the Face interface. We can't easily use a 96 | // single vtable. 97 | // 98 | // For every interface a concrete class implements, we create an array of the concrete vtable_ 99 | // methods for the methods in the interface. 100 | uint32_t iftable_; 101 | // Descriptor for the class such as "java.lang.Class" or "[C". Lazily initialized by ComputeName 102 | uint32_t name_; 103 | // The superclass, or null if this is java.lang.Object or a primitive type. 104 | // 105 | // Note that interfaces have java.lang.Object as their 106 | // superclass. This doesn't match the expectations in JNI 107 | // GetSuperClass or java.lang.Class.getSuperClass() which need to 108 | // check for interfaces and return null. 109 | uint32_t super_class_; 110 | 111 | // If class verify fails, we must return same error on subsequent tries. We may store either 112 | // the class of the error, or an actual instance of Throwable here. 113 | uint32_t verify_error_; 114 | // Virtual method table (vtable), for use by "invoke-virtual". The vtable from the superclass is 115 | // copied in, and virtual methods from our class either replace those from the super or are 116 | // appended. For abstract classes, methods may be created in the vtable that aren't in 117 | // virtual_ methods_ for miranda methods. 118 | uint32_t vtable_; 119 | // Access flags; low 16 bits are defined by VM spec. 120 | // Note: Shuffled back. 121 | uint32_t access_flags_; 122 | // Short cuts to dex_cache_ member for fast compiled code access. 123 | uint64_t dex_cache_strings_; 124 | 125 | // instance fields 126 | // 127 | // These describe the layout of the contents of an Object. 128 | // Note that only the fields directly declared by this class are 129 | // listed in ifields; fields declared by a superclass are listed in 130 | // the superclass's Class.ifields. 131 | // 132 | // ArtFields are allocated as a length prefixed ArtField array, and not an array of pointers to 133 | // ArtFields. 134 | uint64_t ifields_; 135 | // Pointer to an ArtMethod length-prefixed array. All the methods where this class is the place 136 | // where they are logically defined. This includes all private, static, final and virtual methods 137 | // as well as inherited default methods and miranda methods. 138 | // 139 | // The slice methods_ [0, virtual_methods_offset_) are the direct (static, private, init) methods 140 | // declared by this class. 141 | // 142 | // The slice methods_ [virtual_methods_offset_, copied_methods_offset_) are the virtual methods 143 | // declared by this class. 144 | // 145 | // The slice methods_ [copied_methods_offset_, |methods_|) are the methods that are copied from 146 | // interfaces such as miranda or default methods. These are copied for resolution purposes as this 147 | // class is where they are (logically) declared as far as the virtual dispatch is concerned. 148 | // 149 | // Note that this field is used by the native debugger as the unique identifier for the type. 150 | uint64_t methods_; 151 | 152 | // Static fields length-prefixed array. 153 | uint64_t sfields_; 154 | 155 | // Class flags to help speed up visiting object references. 156 | uint32_t class_flags_; 157 | 158 | // Total size of the Class instance; used when allocating storage on gc heap. 159 | // See also object_size_. 160 | uint32_t class_size_; 161 | // Tid used to check for recursive invocation. 162 | pid_t clinit_thread_id_; 163 | // ClassDef index in dex file, -1 if no class definition such as an array. 164 | // TODO: really 16bits 165 | int32_t dex_class_def_idx_; 166 | // Type index in dex file. 167 | // TODO: really 16bits 168 | int32_t dex_type_idx_; 169 | // Number of instance fields that are object refs. 170 | uint32_t num_reference_instance_fields_; 171 | // Number of static fields that are object refs, 172 | uint32_t num_reference_static_fields_; 173 | // Total object size; used when allocating storage on gc heap. 174 | // (For interfaces and abstract classes this will be zero.) 175 | // See also class_size_. 176 | uint32_t object_size_; 177 | // The lower 16 bits contains a Primitive::Type value. The upper 16 178 | // bits contains the size shift of the primitive type. 179 | uint32_t primitive_type_; 180 | // Bitmap of offsets of ifields. 181 | uint32_t reference_instance_offsets_; 182 | // State of class initialization. 183 | Status status_; 184 | // The offset of the first virtual method that is copied from an interface. This includes miranda, 185 | // default, and default-conflict methods. Having a hard limit of ((2 << 16) - 1) for methods 186 | // defined on a single class is well established in Java so we will use only uint16_t's here. 187 | uint16_t copied_methods_offset_; 188 | 189 | // The offset of the first declared virtual methods in the methods_ array. 190 | uint16_t virtual_methods_offset_; 191 | // TODO: ? 192 | // initiating class loader list 193 | // NOTE: for classes with low serialNumber, these are unused, and the 194 | // values are kept in a table in gDvm. 195 | // InitiatingLoaderList initiating_loader_list_; 196 | // The following data exist in real class objects. 197 | // Embedded Imtable, for class object that's not an interface, fixed size. 198 | // ImTableEntry embedded_imtable_[0]; 199 | // Embedded Vtable, for class object that's not an interface, variable size. 200 | // VTableEntry embedded_vtable_[0]; 201 | // Static fields, variable size. 202 | // uint32_t fields_[0]; 203 | // java.lang.Class 204 | static uint32_t java_lang_Class_; 205 | }; 206 | 207 | class ArtField { 208 | public: 209 | uint32_t declaring_class_; 210 | uint32_t access_flags_; 211 | uint32_t field_dex_idx_; 212 | uint32_t offset_; 213 | }; 214 | 215 | class ArtMethod { 216 | public: 217 | 218 | // Field order required by test "ValidateFieldOrderOfJavaCppUnionClasses". 219 | // The class we are a part of. 220 | uint32_t declaring_class_; 221 | // Access flags; low 16 bits are defined by spec. 222 | uint32_t access_flags_; 223 | /* Dex file fields. The defining dex file is available via declaring_class_->dex_cache_ */ 224 | // Offset to the CodeItem. 225 | uint32_t dex_code_item_offset_; 226 | // Index into method_ids of the dex file associated with this method. 227 | uint32_t dex_method_index_; 228 | /* End of dex file fields. */ 229 | // Entry within a dispatch table for this method. For static/direct methods the index is into 230 | // the declaringClass.directMethods, for virtual methods the vtable and for interface methods the 231 | // ifTable. 232 | uint16_t method_index_; 233 | 234 | // The hotness we measure for this method. Incremented by the interpreter. Not atomic, as we allow 235 | // missing increments: if the method is hot, we will see it eventually. 236 | uint16_t hotness_count_; 237 | // Fake padding field gets inserted here. 238 | // Must be the last fields in the method. 239 | // PACKED(4) is necessary for the correctness of 240 | // RoundUp(OFFSETOF_MEMBER(ArtMethod, ptr_sized_fields_), pointer_size). 241 | struct PtrSizedFields { 242 | // Short cuts to declaring_class_->dex_cache_ member for fast compiled code access. 243 | ArtMethod** dex_cache_resolved_methods_; 244 | 245 | // Short cuts to declaring_class_->dex_cache_ member for fast compiled code access. 246 | void* dex_cache_resolved_types_; 247 | 248 | // Pointer to JNI function registered to this method, or a function to resolve the JNI function, 249 | // or the profiling data for non-native methods, or an ImtConflictTable. 250 | void* entry_point_from_jni_; 251 | 252 | // Method dispatch from quick compiled code invokes this pointer which may cause bridging into 253 | // the interpreter. 254 | void* entry_point_from_quick_compiled_code_; 255 | } ptr_sized_fields_; 256 | 257 | }; 258 | 259 | } 260 | 261 | } 262 | -------------------------------------------------------------------------------- /jni/art/art_method_replace.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright (c) 2015, alipay.com 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | /** 19 | * art_method_replace.cpp 20 | * 21 | * @author : sanping.li@alipay.com 22 | * 23 | */ 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | #include 30 | #include 31 | #include 32 | 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | 42 | #include "art.h" 43 | #include "common.h" 44 | 45 | static int apilevel; 46 | 47 | extern jboolean __attribute__ ((visibility ("hidden"))) art_setup(JNIEnv* env, 48 | int level) { 49 | apilevel = level; 50 | return JNI_TRUE; 51 | } 52 | 53 | extern void __attribute__ ((visibility ("hidden"))) art_replaceMethod( 54 | JNIEnv* env, jobject src, jobject dest) { 55 | if (apilevel > 23) { 56 | replace_7_0(env, src, dest); 57 | } else if (apilevel > 22) { 58 | replace_6_0(env, src, dest); 59 | } else if (apilevel > 21) { 60 | replace_5_1(env, src, dest); 61 | } else if (apilevel > 19) { 62 | replace_5_0(env, src, dest); 63 | }else{ 64 | replace_4_4(env, src, dest); 65 | } 66 | } 67 | 68 | extern void __attribute__ ((visibility ("hidden"))) art_setFieldFlag( 69 | JNIEnv* env, jobject field) { 70 | if (apilevel > 23) { 71 | setFieldFlag_7_0(env, field); 72 | } else if (apilevel > 22) { 73 | setFieldFlag_6_0(env, field); 74 | } else if (apilevel > 21) { 75 | setFieldFlag_5_1(env, field); 76 | } else if (apilevel > 19) { 77 | setFieldFlag_5_0(env, field); 78 | }else{ 79 | setFieldFlag_4_4(env, field); 80 | } 81 | } 82 | 83 | -------------------------------------------------------------------------------- /jni/art/art_method_replace_4_4.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright (c) 2015, alipay.com 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | /** 19 | * art_method_replace_4_4.cpp 20 | * 21 | * @author : sanping.li@alipay.com 22 | * 23 | */ 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | #include 30 | #include 31 | #include 32 | 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | 42 | #include "art.h" 43 | #include "art_4_4.h" 44 | #include "common.h" 45 | 46 | void replace_4_4(JNIEnv* env, jobject src, jobject dest) { 47 | art::mirror::ArtMethod* smeth = 48 | (art::mirror::ArtMethod*) env->FromReflectedMethod(src); 49 | 50 | art::mirror::ArtMethod* dmeth = 51 | (art::mirror::ArtMethod*) env->FromReflectedMethod(dest); 52 | 53 | dmeth->declaring_class_->class_loader_ = 54 | smeth->declaring_class_->class_loader_; //for plugin classloader 55 | dmeth->declaring_class_->clinit_thread_id_ = 56 | smeth->declaring_class_->clinit_thread_id_; 57 | dmeth->declaring_class_->status_ = smeth->declaring_class_->status_-1; 58 | //for reflection invoke 59 | reinterpret_cast(dmeth->declaring_class_)->super_class_ = 0; 60 | 61 | smeth->declaring_class_ = dmeth->declaring_class_; 62 | smeth->dex_cache_initialized_static_storage_ = dmeth->dex_cache_initialized_static_storage_; 63 | smeth->access_flags_ = dmeth->access_flags_ | 0x0001; 64 | smeth->dex_cache_resolved_types_ = dmeth->dex_cache_resolved_types_; 65 | smeth->dex_cache_resolved_methods_ = dmeth->dex_cache_resolved_methods_; 66 | smeth->dex_cache_strings_ = dmeth->dex_cache_strings_; 67 | smeth->code_item_offset_ = dmeth->code_item_offset_; 68 | smeth->core_spill_mask_ = dmeth->core_spill_mask_; 69 | smeth->fp_spill_mask_ = dmeth->fp_spill_mask_; 70 | smeth->method_dex_index_ = dmeth->method_dex_index_; 71 | smeth->mapping_table_ = dmeth->mapping_table_; 72 | smeth->method_index_ = dmeth->method_index_; 73 | smeth->gc_map_ = dmeth->gc_map_; 74 | smeth->frame_size_in_bytes_ = dmeth->frame_size_in_bytes_; 75 | smeth->native_method_ = dmeth->native_method_; 76 | smeth->vmap_table_ = dmeth->vmap_table_; 77 | 78 | smeth->entry_point_from_compiled_code_ = dmeth->entry_point_from_compiled_code_; 79 | 80 | smeth->entry_point_from_interpreter_ = dmeth->entry_point_from_interpreter_; 81 | 82 | smeth->method_index_ = dmeth->method_index_; 83 | 84 | LOGD("replace_4_4: %d , %d", smeth->entry_point_from_compiled_code_, 85 | dmeth->entry_point_from_compiled_code_); 86 | 87 | } 88 | 89 | void setFieldFlag_4_4(JNIEnv* env, jobject field) { 90 | art::mirror::ArtField* artField = 91 | (art::mirror::ArtField*) env->FromReflectedField(field); 92 | artField->access_flags_ = artField->access_flags_ & (~0x0002) | 0x0001; 93 | LOGD("setFieldFlag_4_4: %d ", artField->access_flags_); 94 | } 95 | 96 | -------------------------------------------------------------------------------- /jni/art/art_method_replace_5_0.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright (c) 2015, alipay.com 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | /** 19 | * art_method_replace_5_0.cpp 20 | * 21 | * @author : sanping.li@alipay.com 22 | * 23 | */ 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | #include 30 | #include 31 | #include 32 | 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | 42 | #include "art.h" 43 | #include "art_5_0.h" 44 | #include "common.h" 45 | 46 | void replace_5_0(JNIEnv* env, jobject src, jobject dest) { 47 | art::mirror::ArtMethod* smeth = 48 | (art::mirror::ArtMethod*) env->FromReflectedMethod(src); 49 | 50 | art::mirror::ArtMethod* dmeth = 51 | (art::mirror::ArtMethod*) env->FromReflectedMethod(dest); 52 | 53 | reinterpret_cast(dmeth->declaring_class_)->class_loader_ = 54 | reinterpret_cast(smeth->declaring_class_)->class_loader_; //for plugin classloader 55 | reinterpret_cast(dmeth->declaring_class_)->clinit_thread_id_ = 56 | reinterpret_cast(smeth->declaring_class_)->clinit_thread_id_; 57 | reinterpret_cast(dmeth->declaring_class_)->status_ = reinterpret_cast(smeth->declaring_class_)->status_-1; 58 | //for reflection invoke 59 | reinterpret_cast(dmeth->declaring_class_)->super_class_ = 0; 60 | 61 | smeth->declaring_class_ = dmeth->declaring_class_; 62 | smeth->access_flags_ = dmeth->access_flags_ | 0x0001; 63 | smeth->dex_cache_resolved_types_ = dmeth->dex_cache_resolved_types_; 64 | smeth->dex_cache_resolved_methods_ = dmeth->dex_cache_resolved_methods_; 65 | smeth->dex_cache_strings_ = dmeth->dex_cache_strings_; 66 | smeth->dex_code_item_offset_ = dmeth->dex_code_item_offset_; 67 | smeth->dex_method_index_ = dmeth->dex_method_index_; 68 | smeth->gc_map_ = dmeth->gc_map_; 69 | smeth->entry_point_from_jni_ = dmeth->entry_point_from_jni_; 70 | smeth->entry_point_from_quick_compiled_code_ = dmeth->entry_point_from_quick_compiled_code_; 71 | 72 | smeth->entry_point_from_interpreter_ = dmeth->entry_point_from_interpreter_; 73 | 74 | smeth->method_index_ = dmeth->method_index_; 75 | 76 | LOGD("replace_5_0: %d , %d", smeth->entry_point_from_quick_compiled_code_, 77 | dmeth->entry_point_from_quick_compiled_code_); 78 | 79 | } 80 | 81 | void setFieldFlag_5_0(JNIEnv* env, jobject field) { 82 | art::mirror::ArtField* artField = 83 | (art::mirror::ArtField*) env->FromReflectedField(field); 84 | artField->access_flags_ = artField->access_flags_ & (~0x0002) | 0x0001; 85 | LOGD("setFieldFlag_5_0: %d ", artField->access_flags_); 86 | } 87 | 88 | -------------------------------------------------------------------------------- /jni/art/art_method_replace_5_1.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright (c) 2015, alipay.com 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | /** 19 | * art_method_replace_5_1.cpp 20 | * 21 | * @author : sanping.li@alipay.com 22 | * 23 | */ 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | #include 30 | #include 31 | #include 32 | 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | 42 | #include "art.h" 43 | #include "art_5_1.h" 44 | #include "common.h" 45 | 46 | void replace_5_1(JNIEnv* env, jobject src, jobject dest) { 47 | art::mirror::ArtMethod* smeth = 48 | (art::mirror::ArtMethod*) env->FromReflectedMethod(src); 49 | 50 | art::mirror::ArtMethod* dmeth = 51 | (art::mirror::ArtMethod*) env->FromReflectedMethod(dest); 52 | 53 | reinterpret_cast(dmeth->declaring_class_)->class_loader_ = 54 | reinterpret_cast(smeth->declaring_class_)->class_loader_; //for plugin classloader 55 | reinterpret_cast(dmeth->declaring_class_)->clinit_thread_id_ = 56 | reinterpret_cast(smeth->declaring_class_)->clinit_thread_id_; 57 | reinterpret_cast(dmeth->declaring_class_)->status_ = reinterpret_cast(smeth->declaring_class_)->status_-1; 58 | //for reflection invoke 59 | reinterpret_cast(dmeth->declaring_class_)->super_class_ = 0; 60 | 61 | smeth->declaring_class_ = dmeth->declaring_class_; 62 | smeth->dex_cache_resolved_types_ = dmeth->dex_cache_resolved_types_; 63 | smeth->access_flags_ = dmeth->access_flags_ | 0x0001; 64 | smeth->dex_cache_resolved_methods_ = dmeth->dex_cache_resolved_methods_; 65 | smeth->dex_code_item_offset_ = dmeth->dex_code_item_offset_; 66 | smeth->method_index_ = dmeth->method_index_; 67 | smeth->dex_method_index_ = dmeth->dex_method_index_; 68 | 69 | smeth->ptr_sized_fields_.entry_point_from_interpreter_ = 70 | dmeth->ptr_sized_fields_.entry_point_from_interpreter_; 71 | 72 | smeth->ptr_sized_fields_.entry_point_from_jni_ = 73 | dmeth->ptr_sized_fields_.entry_point_from_jni_; 74 | smeth->ptr_sized_fields_.entry_point_from_quick_compiled_code_ = 75 | dmeth->ptr_sized_fields_.entry_point_from_quick_compiled_code_; 76 | 77 | LOGD("replace_5_1: %d , %d", 78 | smeth->ptr_sized_fields_.entry_point_from_quick_compiled_code_, 79 | dmeth->ptr_sized_fields_.entry_point_from_quick_compiled_code_); 80 | 81 | } 82 | 83 | void setFieldFlag_5_1(JNIEnv* env, jobject field) { 84 | art::mirror::ArtField* artField = 85 | (art::mirror::ArtField*) env->FromReflectedField(field); 86 | artField->access_flags_ = artField->access_flags_ & (~0x0002) | 0x0001; 87 | LOGD("setFieldFlag_5_1: %d ", artField->access_flags_); 88 | } 89 | -------------------------------------------------------------------------------- /jni/art/art_method_replace_6_0.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright (c) 2015, alipay.com 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | /** 19 | * art_method_replace_6_0.cpp 20 | * 21 | * @author : sanping.li@alipay.com 22 | * 23 | */ 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | #include 30 | #include 31 | #include 32 | 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | 42 | #include "art.h" 43 | #include "art_6_0.h" 44 | #include "common.h" 45 | 46 | void replace_6_0(JNIEnv* env, jobject src, jobject dest) { 47 | art::mirror::ArtMethod* smeth = 48 | (art::mirror::ArtMethod*) env->FromReflectedMethod(src); 49 | 50 | art::mirror::ArtMethod* dmeth = 51 | (art::mirror::ArtMethod*) env->FromReflectedMethod(dest); 52 | 53 | reinterpret_cast(dmeth->declaring_class_)->class_loader_ = 54 | reinterpret_cast(smeth->declaring_class_)->class_loader_; //for plugin classloader 55 | reinterpret_cast(dmeth->declaring_class_)->clinit_thread_id_ = 56 | reinterpret_cast(smeth->declaring_class_)->clinit_thread_id_; 57 | reinterpret_cast(dmeth->declaring_class_)->status_ = reinterpret_cast(smeth->declaring_class_)->status_-1; 58 | //for reflection invoke 59 | reinterpret_cast(dmeth->declaring_class_)->super_class_ = 0; 60 | 61 | smeth->declaring_class_ = dmeth->declaring_class_; 62 | smeth->dex_cache_resolved_methods_ = dmeth->dex_cache_resolved_methods_; 63 | smeth->dex_cache_resolved_types_ = dmeth->dex_cache_resolved_types_; 64 | smeth->access_flags_ = dmeth->access_flags_ | 0x0001; 65 | smeth->dex_code_item_offset_ = dmeth->dex_code_item_offset_; 66 | smeth->dex_method_index_ = dmeth->dex_method_index_; 67 | smeth->method_index_ = dmeth->method_index_; 68 | 69 | smeth->ptr_sized_fields_.entry_point_from_interpreter_ = 70 | dmeth->ptr_sized_fields_.entry_point_from_interpreter_; 71 | 72 | smeth->ptr_sized_fields_.entry_point_from_jni_ = 73 | dmeth->ptr_sized_fields_.entry_point_from_jni_; 74 | smeth->ptr_sized_fields_.entry_point_from_quick_compiled_code_ = 75 | dmeth->ptr_sized_fields_.entry_point_from_quick_compiled_code_; 76 | 77 | LOGD("replace_6_0: %d , %d", 78 | smeth->ptr_sized_fields_.entry_point_from_quick_compiled_code_, 79 | dmeth->ptr_sized_fields_.entry_point_from_quick_compiled_code_); 80 | } 81 | 82 | void setFieldFlag_6_0(JNIEnv* env, jobject field) { 83 | art::mirror::ArtField* artField = 84 | (art::mirror::ArtField*) env->FromReflectedField(field); 85 | artField->access_flags_ = artField->access_flags_ & (~0x0002) | 0x0001; 86 | LOGD("setFieldFlag_6_0: %d ", artField->access_flags_); 87 | } 88 | -------------------------------------------------------------------------------- /jni/art/art_method_replace_7_0.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright (c) 2015, alipay.com 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | /** 19 | * art_method_replace_7_0.cpp 20 | * 21 | * @author : sanping.li@alipay.com 22 | * 23 | */ 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | #include 30 | #include 31 | #include 32 | 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | 42 | #include "art.h" 43 | #include "art_7_0.h" 44 | #include "common.h" 45 | 46 | void replace_7_0(JNIEnv* env, jobject src, jobject dest) { 47 | art::mirror::ArtMethod* smeth = 48 | (art::mirror::ArtMethod*) env->FromReflectedMethod(src); 49 | 50 | art::mirror::ArtMethod* dmeth = 51 | (art::mirror::ArtMethod*) env->FromReflectedMethod(dest); 52 | 53 | // reinterpret_cast(smeth->declaring_class_)->class_loader_ = 54 | // reinterpret_cast(dmeth->declaring_class_)->class_loader_; //for plugin classloader 55 | reinterpret_cast(dmeth->declaring_class_)->clinit_thread_id_ = 56 | reinterpret_cast(smeth->declaring_class_)->clinit_thread_id_; 57 | reinterpret_cast(dmeth->declaring_class_)->status_ = 58 | reinterpret_cast(smeth->declaring_class_)->status_ -1; 59 | //for reflection invoke 60 | reinterpret_cast(dmeth->declaring_class_)->super_class_ = 0; 61 | 62 | smeth->declaring_class_ = dmeth->declaring_class_; 63 | smeth->access_flags_ = dmeth->access_flags_ | 0x0001; 64 | smeth->dex_code_item_offset_ = dmeth->dex_code_item_offset_; 65 | smeth->dex_method_index_ = dmeth->dex_method_index_; 66 | smeth->method_index_ = dmeth->method_index_; 67 | smeth->hotness_count_ = dmeth->hotness_count_; 68 | 69 | smeth->ptr_sized_fields_.dex_cache_resolved_methods_ = 70 | dmeth->ptr_sized_fields_.dex_cache_resolved_methods_; 71 | smeth->ptr_sized_fields_.dex_cache_resolved_types_ = 72 | dmeth->ptr_sized_fields_.dex_cache_resolved_types_; 73 | 74 | smeth->ptr_sized_fields_.entry_point_from_jni_ = 75 | dmeth->ptr_sized_fields_.entry_point_from_jni_; 76 | smeth->ptr_sized_fields_.entry_point_from_quick_compiled_code_ = 77 | dmeth->ptr_sized_fields_.entry_point_from_quick_compiled_code_; 78 | 79 | LOGD("replace_7_0: %d , %d", 80 | smeth->ptr_sized_fields_.entry_point_from_quick_compiled_code_, 81 | dmeth->ptr_sized_fields_.entry_point_from_quick_compiled_code_); 82 | 83 | } 84 | 85 | void setFieldFlag_7_0(JNIEnv* env, jobject field) { 86 | art::mirror::ArtField* artField = 87 | (art::mirror::ArtField*) env->FromReflectedField(field); 88 | artField->access_flags_ = artField->access_flags_ & (~0x0002) | 0x0001; 89 | LOGD("setFieldFlag_7_0: %d ", artField->access_flags_); 90 | } 91 | -------------------------------------------------------------------------------- /jni/common.h: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright (c) 2015, alipay.com 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | /* 19 | * common.h 20 | * 21 | * @author : sanping.li@alipay.com 22 | * 23 | */ 24 | 25 | #ifndef COMMON_H_ 26 | #define COMMON_H_ 27 | 28 | #include 29 | #include 30 | 31 | #define LOG_TAG "AndFix" 32 | #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__) 33 | #define LOGW(...) __android_log_print(ANDROID_LOG_WARN,LOG_TAG,__VA_ARGS__) 34 | #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__) \ 35 | 36 | #endif /* COMMON_H_ */ 37 | -------------------------------------------------------------------------------- /jni/dalvik/dalvik.h: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright (c) 2008 The Android Open Source Project 4 | * Copyright (c) 2015, alipay.com 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | /* 20 | * dalvik.h 21 | * 22 | * 23 | * @author : sanping.li@alipay.com 24 | * 25 | */ 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | 32 | #include /* C99 */ 33 | 34 | #include "common.h" 35 | 36 | typedef uint8_t u1; 37 | typedef uint16_t u2; 38 | typedef uint32_t u4; 39 | typedef uint64_t u8; 40 | typedef int8_t s1; 41 | typedef int16_t s2; 42 | typedef int32_t s4; 43 | typedef int64_t s8; 44 | 45 | /* 46 | * access flags and masks; the "standard" ones are all <= 0x4000 47 | * 48 | * Note: There are related declarations in vm/oo/Object.h in the ClassFlags 49 | * enum. 50 | */ 51 | enum { 52 | ACC_PUBLIC = 0x00000001, // class, field, method, ic 53 | ACC_PRIVATE = 0x00000002, // field, method, ic 54 | ACC_PROTECTED = 0x00000004, // field, method, ic 55 | ACC_STATIC = 0x00000008, // field, method, ic 56 | ACC_FINAL = 0x00000010, // class, field, method, ic 57 | ACC_SYNCHRONIZED = 0x00000020, // method (only allowed on natives) 58 | ACC_SUPER = 0x00000020, // class (not used in Dalvik) 59 | ACC_VOLATILE = 0x00000040, // field 60 | ACC_BRIDGE = 0x00000040, // method (1.5) 61 | ACC_TRANSIENT = 0x00000080, // field 62 | ACC_VARARGS = 0x00000080, // method (1.5) 63 | ACC_NATIVE = 0x00000100, // method 64 | ACC_INTERFACE = 0x00000200, // class, ic 65 | ACC_ABSTRACT = 0x00000400, // class, method, ic 66 | ACC_STRICT = 0x00000800, // method 67 | ACC_SYNTHETIC = 0x00001000, // field, method, ic 68 | ACC_ANNOTATION = 0x00002000, // class, ic (1.5) 69 | ACC_ENUM = 0x00004000, // class, field, ic (1.5) 70 | ACC_CONSTRUCTOR = 0x00010000, // method (Dalvik only) 71 | ACC_DECLARED_SYNCHRONIZED = 0x00020000, // method (Dalvik only) 72 | ACC_CLASS_MASK = (ACC_PUBLIC | ACC_FINAL | ACC_INTERFACE | ACC_ABSTRACT 73 | | ACC_SYNTHETIC | ACC_ANNOTATION | ACC_ENUM), 74 | ACC_INNER_CLASS_MASK = (ACC_CLASS_MASK | ACC_PRIVATE | ACC_PROTECTED 75 | | ACC_STATIC), 76 | ACC_FIELD_MASK = (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED | ACC_STATIC 77 | | ACC_FINAL | ACC_VOLATILE | ACC_TRANSIENT | ACC_SYNTHETIC 78 | | ACC_ENUM), 79 | ACC_METHOD_MASK = (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED | ACC_STATIC 80 | | ACC_FINAL | ACC_SYNCHRONIZED | ACC_BRIDGE | ACC_VARARGS 81 | | ACC_NATIVE | ACC_ABSTRACT | ACC_STRICT | ACC_SYNTHETIC 82 | | ACC_CONSTRUCTOR | ACC_DECLARED_SYNCHRONIZED), 83 | }; 84 | 85 | typedef struct DexProto { 86 | u4* dexFile; /* file the idx refers to */ 87 | u4 protoIdx; /* index into proto_ids table of dexFile */ 88 | } DexProto; 89 | 90 | typedef void (*DalvikBridgeFunc)(const u4* args, void* pResult, 91 | const void* method, void* self); 92 | 93 | struct Field { 94 | void* clazz; /* class in which the field is declared */ 95 | const char* name; 96 | const char* signature; /* e.g. "I", "[C", "Landroid/os/Debug;" */ 97 | u4 accessFlags; 98 | }; 99 | 100 | struct Method; 101 | struct ClassObject; 102 | 103 | typedef struct Object { 104 | /* ptr to class object */ 105 | struct ClassObject* clazz; 106 | 107 | /* 108 | * A word containing either a "thin" lock or a "fat" monitor. See 109 | * the comments in Sync.c for a description of its layout. 110 | */ 111 | u4 lock; 112 | } Object; 113 | 114 | struct InitiatingLoaderList { 115 | /* a list of initiating loader Objects; grown and initialized on demand */ 116 | void** initiatingLoaders; 117 | /* count of loaders in the above list */ 118 | int initiatingLoaderCount; 119 | }; 120 | 121 | enum PrimitiveType { 122 | PRIM_NOT = 0, /* value is a reference type, not a primitive type */ 123 | PRIM_VOID = 1, 124 | PRIM_BOOLEAN = 2, 125 | PRIM_BYTE = 3, 126 | PRIM_SHORT = 4, 127 | PRIM_CHAR = 5, 128 | PRIM_INT = 6, 129 | PRIM_LONG = 7, 130 | PRIM_FLOAT = 8, 131 | PRIM_DOUBLE = 9, 132 | }typedef PrimitiveType; 133 | 134 | enum ClassStatus { 135 | CLASS_ERROR = -1, 136 | 137 | CLASS_NOTREADY = 0, CLASS_IDX = 1, /* loaded, DEX idx in super or ifaces */ 138 | CLASS_LOADED = 2, /* DEX idx values resolved */ 139 | CLASS_RESOLVED = 3, /* part of linking */ 140 | CLASS_VERIFYING = 4, /* in the process of being verified */ 141 | CLASS_VERIFIED = 5, /* logically part of linking; done pre-init */ 142 | CLASS_INITIALIZING = 6, /* class init in progress */ 143 | CLASS_INITIALIZED = 7, /* ready to go */ 144 | }typedef ClassStatus; 145 | 146 | typedef struct ClassObject { 147 | struct Object o; // emulate C++ inheritance, Collin 148 | 149 | /* leave space for instance data; we could access fields directly if we 150 | freeze the definition of java/lang/Class */ 151 | u4 instanceData[4]; 152 | 153 | /* UTF-8 descriptor for the class; from constant pool, or on heap 154 | if generated ("[C") */ 155 | const char* descriptor; 156 | char* descriptorAlloc; 157 | 158 | /* access flags; low 16 bits are defined by VM spec */ 159 | u4 accessFlags; 160 | 161 | /* VM-unique class serial number, nonzero, set very early */ 162 | u4 serialNumber; 163 | 164 | /* DexFile from which we came; needed to resolve constant pool entries */ 165 | /* (will be NULL for VM-generated, e.g. arrays and primitive classes) */ 166 | void* pDvmDex; 167 | 168 | /* state of class initialization */ 169 | ClassStatus status; 170 | 171 | /* if class verify fails, we must return same error on subsequent tries */ 172 | struct ClassObject* verifyErrorClass; 173 | 174 | /* threadId, used to check for recursive invocation */ 175 | u4 initThreadId; 176 | 177 | /* 178 | * Total object size; used when allocating storage on gc heap. (For 179 | * interfaces and abstract classes this will be zero.) 180 | */ 181 | size_t objectSize; 182 | 183 | /* arrays only: class object for base element, for instanceof/checkcast 184 | (for String[][][], this will be String) */ 185 | struct ClassObject* elementClass; 186 | 187 | /* arrays only: number of dimensions, e.g. int[][] is 2 */ 188 | int arrayDim; 189 | PrimitiveType primitiveType; 190 | 191 | /* superclass, or NULL if this is java.lang.Object */ 192 | struct ClassObject* super; 193 | 194 | /* defining class loader, or NULL for the "bootstrap" system loader */ 195 | struct Object* classLoader; 196 | 197 | struct InitiatingLoaderList initiatingLoaderList; 198 | 199 | /* array of interfaces this class implements directly */ 200 | int interfaceCount; 201 | struct ClassObject** interfaces; 202 | 203 | /* static, private, and methods */ 204 | int directMethodCount; 205 | struct Method* directMethods; 206 | 207 | /* virtual methods defined in this class; invoked through vtable */ 208 | int virtualMethodCount; 209 | struct Method* virtualMethods; 210 | 211 | /* 212 | * Virtual method table (vtable), for use by "invoke-virtual". The 213 | * vtable from the superclass is copied in, and virtual methods from 214 | * our class either replace those from the super or are appended. 215 | */ 216 | int vtableCount; 217 | struct Method** vtable; 218 | 219 | } ClassObject; 220 | 221 | typedef struct Method { 222 | struct ClassObject *clazz; 223 | u4 accessFlags; 224 | 225 | u2 methodIndex; 226 | 227 | u2 registersSize; /* ins + locals */ 228 | u2 outsSize; 229 | u2 insSize; 230 | 231 | /* method name, e.g. "" or "eatLunch" */ 232 | const char* name; 233 | 234 | /* 235 | * Method prototype descriptor string (return and argument types). 236 | * 237 | * TODO: This currently must specify the DexFile as well as the proto_ids 238 | * index, because generated Proxy classes don't have a DexFile. We can 239 | * remove the DexFile* and reduce the size of this struct if we generate 240 | * a DEX for proxies. 241 | */ 242 | DexProto prototype; 243 | 244 | /* short-form method descriptor string */ 245 | const char* shorty; 246 | 247 | /* 248 | * The remaining items are not used for abstract or native methods. 249 | * (JNI is currently hijacking "insns" as a function pointer, set 250 | * after the first call. For internal-native this stays null.) 251 | */ 252 | 253 | /* the actual code */ 254 | u2* insns; 255 | 256 | /* cached JNI argument and return-type hints */ 257 | int jniArgInfo; 258 | 259 | /* 260 | * Native method ptr; could be actual function or a JNI bridge. We 261 | * don't currently discriminate between DalvikBridgeFunc and 262 | * DalvikNativeFunc; the former takes an argument superset (i.e. two 263 | * extra args) which will be ignored. If necessary we can use 264 | * insns==NULL to detect JNI bridge vs. internal native. 265 | */ 266 | DalvikBridgeFunc nativeFunc; 267 | 268 | #ifdef WITH_PROFILER 269 | bool inProfile; 270 | #endif 271 | #ifdef WITH_DEBUGGER 272 | short debugBreakpointCount; 273 | #endif 274 | 275 | bool fastJni; 276 | 277 | /* 278 | * JNI: true if this method has no reference arguments. This lets the JNI 279 | * bridge avoid scanning the shorty for direct pointers that need to be 280 | * converted to local references. 281 | * 282 | * TODO: replace this with a list of indexes of the reference arguments. 283 | */ 284 | bool noRef; 285 | 286 | } Method; 287 | 288 | typedef Object* (*dvmDecodeIndirectRef_func)(void* self, jobject jobj); 289 | typedef void* (*dvmThreadSelf_func)(); 290 | 291 | dvmDecodeIndirectRef_func dvmDecodeIndirectRef_fnPtr; 292 | dvmThreadSelf_func dvmThreadSelf_fnPtr; 293 | 294 | jmethodID jClassMethod; 295 | -------------------------------------------------------------------------------- /jni/dalvik/dalvik_method_replace.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright (c) 2015, alipay.com 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | /** 19 | * dalvik_method_replace.cpp 20 | * 21 | * @author : sanping.li@alipay.com 22 | * 23 | */ 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | #include 30 | #include 31 | #include 32 | 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | 42 | #include "dalvik.h" 43 | #include "common.h" 44 | 45 | static void* dvm_dlsym(void *hand, const char *name) { 46 | void* ret = dlsym(hand, name); 47 | char msg[1024] = { 0 }; 48 | snprintf(msg, sizeof(msg) - 1, "0x%x", ret); 49 | LOGD("%s = %s\n", name, msg); 50 | return ret; 51 | } 52 | 53 | extern jboolean __attribute__ ((visibility ("hidden"))) dalvik_setup( 54 | JNIEnv* env, int apilevel) { 55 | void* dvm_hand = dlopen("libdvm.so", RTLD_NOW); 56 | if (dvm_hand) { 57 | dvmDecodeIndirectRef_fnPtr = dvm_dlsym(dvm_hand, 58 | apilevel > 10 ? 59 | "_Z20dvmDecodeIndirectRefP6ThreadP8_jobject" : 60 | "dvmDecodeIndirectRef"); 61 | if (!dvmDecodeIndirectRef_fnPtr) { 62 | return JNI_FALSE; 63 | } 64 | dvmThreadSelf_fnPtr = dvm_dlsym(dvm_hand, 65 | apilevel > 10 ? "_Z13dvmThreadSelfv" : "dvmThreadSelf"); 66 | if (!dvmThreadSelf_fnPtr) { 67 | return JNI_FALSE; 68 | } 69 | jclass clazz = env->FindClass("java/lang/reflect/Method"); 70 | jClassMethod = env->GetMethodID(clazz, "getDeclaringClass", 71 | "()Ljava/lang/Class;"); 72 | 73 | return JNI_TRUE; 74 | } else { 75 | return JNI_FALSE; 76 | } 77 | } 78 | 79 | extern void __attribute__ ((visibility ("hidden"))) dalvik_replaceMethod( 80 | JNIEnv* env, jobject src, jobject dest) { 81 | jobject clazz = env->CallObjectMethod(dest, jClassMethod); 82 | ClassObject* clz = (ClassObject*) dvmDecodeIndirectRef_fnPtr( 83 | dvmThreadSelf_fnPtr(), clazz); 84 | clz->status = CLASS_INITIALIZED; 85 | 86 | Method* meth = (Method*) env->FromReflectedMethod(src); 87 | Method* target = (Method*) env->FromReflectedMethod(dest); 88 | LOGD("dalvikMethod: %s", meth->name); 89 | 90 | // meth->clazz = target->clazz; 91 | meth->accessFlags |= ACC_PUBLIC; 92 | meth->methodIndex = target->methodIndex; 93 | meth->jniArgInfo = target->jniArgInfo; 94 | meth->registersSize = target->registersSize; 95 | meth->outsSize = target->outsSize; 96 | meth->insSize = target->insSize; 97 | 98 | meth->prototype = target->prototype; 99 | meth->insns = target->insns; 100 | meth->nativeFunc = target->nativeFunc; 101 | } 102 | 103 | extern void dalvik_setFieldFlag(JNIEnv* env, jobject field) { 104 | Field* dalvikField = (Field*) env->FromReflectedField(field); 105 | dalvikField->accessFlags = dalvikField->accessFlags & (~ACC_PRIVATE) 106 | | ACC_PUBLIC; 107 | LOGD("dalvik_setFieldFlag: %d ", dalvikField->accessFlags); 108 | } 109 | -------------------------------------------------------------------------------- /libs/arm64-v8a/libandfix.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alibaba/AndFix/0351a4bc38a7d30bc61a6d3e74777d4eff4ad5e9/libs/arm64-v8a/libandfix.so -------------------------------------------------------------------------------- /libs/armeabi-v7a/libandfix.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alibaba/AndFix/0351a4bc38a7d30bc61a6d3e74777d4eff4ad5e9/libs/armeabi-v7a/libandfix.so -------------------------------------------------------------------------------- /libs/armeabi/libandfix.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alibaba/AndFix/0351a4bc38a7d30bc61a6d3e74777d4eff4ad5e9/libs/armeabi/libandfix.so -------------------------------------------------------------------------------- /libs/mips/libandfix.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alibaba/AndFix/0351a4bc38a7d30bc61a6d3e74777d4eff4ad5e9/libs/mips/libandfix.so -------------------------------------------------------------------------------- /libs/mips64/libandfix.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alibaba/AndFix/0351a4bc38a7d30bc61a6d3e74777d4eff4ad5e9/libs/mips64/libandfix.so -------------------------------------------------------------------------------- /libs/x86/libandfix.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alibaba/AndFix/0351a4bc38a7d30bc61a6d3e74777d4eff4ad5e9/libs/x86/libandfix.so -------------------------------------------------------------------------------- /libs/x86_64/libandfix.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alibaba/AndFix/0351a4bc38a7d30bc61a6d3e74777d4eff4ad5e9/libs/x86_64/libandfix.so -------------------------------------------------------------------------------- /local.properties: -------------------------------------------------------------------------------- 1 | bintray.apikey=0967e67a6dd861e40b5bc3148985e502712396da 2 | bintray.user=supern -------------------------------------------------------------------------------- /proguard-project.txt: -------------------------------------------------------------------------------- 1 | # To enable ProGuard in your project, edit project.properties 2 | # to define the proguard.config property as described in that file. 3 | # 4 | # Add project specific ProGuard rules here. 5 | # By default, the flags in this file are appended to flags specified 6 | # in ${sdk.dir}/tools/proguard/proguard-android.txt 7 | # You can edit the include path and order by changing the ProGuard 8 | # include property in project.properties. 9 | # 10 | # For more details, see 11 | # http://developer.android.com/guide/developing/tools/proguard.html 12 | 13 | # Add any project specific keep options here: 14 | 15 | # If your project uses WebView with JS, uncomment the following 16 | # and specify the fully qualified class name to the JavaScript interface 17 | # class: 18 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 19 | # public *; 20 | #} 21 | -------------------------------------------------------------------------------- /samples/AndFixDemo/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .classpath 3 | .project 4 | /.settings 5 | /bin 6 | /gen 7 | /patch 8 | project.properties 9 | /assets 10 | -------------------------------------------------------------------------------- /samples/AndFixDemo/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | 8 | 9 | 12 | 13 | 17 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /samples/AndFixDemo/ic_launcher-web.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alibaba/AndFix/0351a4bc38a7d30bc61a6d3e74777d4eff4ad5e9/samples/AndFixDemo/ic_launcher-web.png -------------------------------------------------------------------------------- /samples/AndFixDemo/proguard-project.txt: -------------------------------------------------------------------------------- 1 | # To enable ProGuard in your project, edit project.properties 2 | # to define the proguard.config property as described in that file. 3 | # 4 | # Add project specific ProGuard rules here. 5 | # By default, the flags in this file are appended to flags specified 6 | # in ${sdk.dir}/tools/proguard/proguard-android.txt 7 | # You can edit the include path and order by changing the ProGuard 8 | # include property in project.properties. 9 | # 10 | # For more details, see 11 | # http://developer.android.com/guide/developing/tools/proguard.html 12 | 13 | # Add any project specific keep options here: 14 | 15 | # If your project uses WebView with JS, uncomment the following 16 | # and specify the fully qualified class name to the JavaScript interface 17 | # class: 18 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 19 | # public *; 20 | #} 21 | -------------------------------------------------------------------------------- /samples/AndFixDemo/res/drawable-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alibaba/AndFix/0351a4bc38a7d30bc61a6d3e74777d4eff4ad5e9/samples/AndFixDemo/res/drawable-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /samples/AndFixDemo/res/drawable-ldpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alibaba/AndFix/0351a4bc38a7d30bc61a6d3e74777d4eff4ad5e9/samples/AndFixDemo/res/drawable-ldpi/ic_launcher.png -------------------------------------------------------------------------------- /samples/AndFixDemo/res/drawable-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alibaba/AndFix/0351a4bc38a7d30bc61a6d3e74777d4eff4ad5e9/samples/AndFixDemo/res/drawable-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /samples/AndFixDemo/res/drawable-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alibaba/AndFix/0351a4bc38a7d30bc61a6d3e74777d4eff4ad5e9/samples/AndFixDemo/res/drawable-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /samples/AndFixDemo/res/drawable-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alibaba/AndFix/0351a4bc38a7d30bc61a6d3e74777d4eff4ad5e9/samples/AndFixDemo/res/drawable-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /samples/AndFixDemo/res/layout/main.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /samples/AndFixDemo/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | AndFixDemo 4 | 5 | 6 | -------------------------------------------------------------------------------- /samples/AndFixDemo/src/com/euler/andfix/MainActivity.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright (c) 2015, alipay.com 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package com.euler.andfix; 19 | 20 | import android.app.Activity; 21 | import android.os.Bundle; 22 | import android.util.Log; 23 | 24 | import com.euler.test.A; 25 | 26 | /** 27 | * sample activity 28 | * 29 | * @author luohou 30 | * @author sanping.li@alipay.com 31 | * 32 | */ 33 | public class MainActivity extends Activity { 34 | private static final String TAG = "euler"; 35 | 36 | @Override 37 | public void onCreate(Bundle savedInstanceState) { 38 | super.onCreate(savedInstanceState); 39 | Log.e(TAG, A.a("good")); 40 | Log.e(TAG, "" + new A().b("s1", "s2")); 41 | Log.e(TAG, "" + new A().getI()); 42 | } 43 | 44 | @Override 45 | protected void onDestroy() { 46 | super.onDestroy(); 47 | android.os.Process.killProcess(android.os.Process.myPid()); 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /samples/AndFixDemo/src/com/euler/andfix/MainApplication.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright (c) 2015, alipay.com 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package com.euler.andfix; 19 | 20 | import java.io.IOException; 21 | 22 | import android.app.Application; 23 | import android.os.Environment; 24 | import android.util.Log; 25 | 26 | import com.alipay.euler.andfix.patch.PatchManager; 27 | 28 | /** 29 | * sample application 30 | * 31 | * @author sanping.li@alipay.com 32 | * 33 | */ 34 | public class MainApplication extends Application { 35 | private static final String TAG = "euler"; 36 | 37 | private static final String APATCH_PATH = "/out.apatch"; 38 | /** 39 | * patch manager 40 | */ 41 | private PatchManager mPatchManager; 42 | 43 | @Override 44 | public void onCreate() { 45 | super.onCreate(); 46 | // initialize 47 | mPatchManager = new PatchManager(this); 48 | mPatchManager.init("1.0"); 49 | Log.d(TAG, "inited."); 50 | 51 | // load patch 52 | mPatchManager.loadPatch(); 53 | Log.d(TAG, "apatch loaded."); 54 | 55 | // add patch at runtime 56 | try { 57 | // .apatch file path 58 | String patchFileString = Environment.getExternalStorageDirectory() 59 | .getAbsolutePath() + APATCH_PATH; 60 | mPatchManager.addPatch(patchFileString); 61 | Log.d(TAG, "apatch:" + patchFileString + " added."); 62 | } catch (IOException e) { 63 | Log.e(TAG, "", e); 64 | } 65 | 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /samples/AndFixDemo/src/com/euler/test/A.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright (c) 2015, alipay.com 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package com.euler.test; 19 | 20 | import android.util.Log; 21 | 22 | /** 23 | * the class will be fix 24 | * 25 | * copy {@link Fix} to here, and then generate patch (.apatch file) 26 | * 27 | * @author sanping.li@alipay.com 28 | * 29 | */ 30 | public class A { 31 | String s = "s"; 32 | private static O o = new O("a"); 33 | static int i = 10; 34 | 35 | public static String a(String str) { 36 | Log.i("euler", "fix error"); 37 | return "a"; 38 | } 39 | 40 | public int b(String s1, String s2) { 41 | Log.i("euler", "fix error"); 42 | Log.i("euler", o.s); 43 | return 0; 44 | } 45 | 46 | public int getI() { 47 | return i; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /samples/AndFixDemo/src/com/euler/test/F.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright (c) 2015, alipay.com 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package com.euler.test; 19 | 20 | /** 21 | * @author sanping.li@alipay.com 22 | * 23 | */ 24 | public class F { 25 | 26 | } 27 | -------------------------------------------------------------------------------- /samples/AndFixDemo/src/com/euler/test/Fix.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright (c) 2015, alipay.com 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package com.euler.test; 19 | 20 | import android.util.Log; 21 | 22 | /** 23 | * new version of {@link A} 24 | * 25 | * @author sanping.li@alipay.com 26 | * 27 | */ 28 | public class Fix { 29 | String s = "s"; 30 | private static O o = new O("fix"); 31 | static int i = 11; 32 | 33 | public static String a(String str) { 34 | Log.d("qq", str); 35 | Log.i("euler", "fix succes"); 36 | return "b"; 37 | } 38 | 39 | public int b(String s1, String s2) { 40 | Log.e("euler", s1); 41 | Log.e("euler", i + "==" + c()); 42 | Log.i("euler", "fix succes" + s); 43 | Log.i("euler", o.s); 44 | return 0; 45 | } 46 | 47 | private String c() { 48 | return "a"; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /samples/AndFixDemo/src/com/euler/test/O.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright (c) 2015, alipay.com 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package com.euler.test; 19 | 20 | /** 21 | * @author sanping.li@alipay.com 22 | * 23 | */ 24 | public class O { 25 | public String s = "s"; 26 | 27 | public O(String s) { 28 | this.s = s; 29 | } 30 | 31 | @Override 32 | public String toString() { 33 | return s; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'andfix' 2 | -------------------------------------------------------------------------------- /src/com/alipay/euler/andfix/AndFix.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright (c) 2015, alipay.com 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package com.alipay.euler.andfix; 19 | 20 | import java.lang.reflect.Field; 21 | import java.lang.reflect.Method; 22 | 23 | import android.os.Build; 24 | import android.util.Log; 25 | 26 | /** 27 | * Native interface 28 | * 29 | * @author sanping.li@alipay.com 30 | * 31 | */ 32 | public class AndFix { 33 | private static final String TAG = "AndFix"; 34 | 35 | static { 36 | try { 37 | Runtime.getRuntime().loadLibrary("andfix"); 38 | } catch (Throwable e) { 39 | Log.e(TAG, "loadLibrary", e); 40 | } 41 | } 42 | 43 | private static native boolean setup(boolean isArt, int apilevel); 44 | 45 | private static native void replaceMethod(Method dest, Method src); 46 | 47 | private static native void setFieldFlag(Field field); 48 | 49 | /** 50 | * replace method's body 51 | * 52 | * @param src 53 | * source method 54 | * @param dest 55 | * target method 56 | * 57 | */ 58 | public static void addReplaceMethod(Method src, Method dest) { 59 | try { 60 | replaceMethod(src, dest); 61 | initFields(dest.getDeclaringClass()); 62 | } catch (Throwable e) { 63 | Log.e(TAG, "addReplaceMethod", e); 64 | } 65 | } 66 | 67 | /** 68 | * initialize the target class, and modify access flag of class’ fields to 69 | * public 70 | * 71 | * @param clazz 72 | * target class 73 | * @return initialized class 74 | */ 75 | public static Class initTargetClass(Class clazz) { 76 | try { 77 | Class targetClazz = Class.forName(clazz.getName(), true, 78 | clazz.getClassLoader()); 79 | 80 | initFields(targetClazz); 81 | return targetClazz; 82 | } catch (Exception e) { 83 | Log.e(TAG, "initTargetClass", e); 84 | } 85 | return null; 86 | } 87 | 88 | /** 89 | * modify access flag of class’ fields to public 90 | * 91 | * @param clazz 92 | * class 93 | */ 94 | private static void initFields(Class clazz) { 95 | Field[] srcFields = clazz.getDeclaredFields(); 96 | for (Field srcField : srcFields) { 97 | Log.d(TAG, "modify " + clazz.getName() + "." + srcField.getName() 98 | + " flag:"); 99 | setFieldFlag(srcField); 100 | } 101 | } 102 | 103 | /** 104 | * initialize 105 | * 106 | * @return true if initialize success 107 | */ 108 | public static boolean setup() { 109 | try { 110 | final String vmVersion = System.getProperty("java.vm.version"); 111 | boolean isArt = vmVersion != null && vmVersion.startsWith("2"); 112 | int apilevel = Build.VERSION.SDK_INT; 113 | return setup(isArt, apilevel); 114 | } catch (Exception e) { 115 | Log.e(TAG, "setup", e); 116 | return false; 117 | } 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /src/com/alipay/euler/andfix/AndFixManager.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright (c) 2015, alipay.com 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package com.alipay.euler.andfix; 19 | 20 | import java.io.File; 21 | import java.io.IOException; 22 | import java.lang.reflect.Method; 23 | import java.util.Enumeration; 24 | import java.util.List; 25 | import java.util.Map; 26 | import java.util.concurrent.ConcurrentHashMap; 27 | 28 | import android.content.Context; 29 | import android.util.Log; 30 | 31 | import com.alipay.euler.andfix.annotation.MethodReplace; 32 | import com.alipay.euler.andfix.security.SecurityChecker; 33 | 34 | import dalvik.system.DexFile; 35 | 36 | /** 37 | * AndFix Manager 38 | * 39 | * @author sanping.li@alipay.com 40 | * 41 | */ 42 | public class AndFixManager { 43 | private static final String TAG = "AndFixManager"; 44 | 45 | private static final String DIR = "apatch_opt"; 46 | 47 | /** 48 | * context 49 | */ 50 | private final Context mContext; 51 | 52 | /** 53 | * classes will be fixed 54 | */ 55 | private static Map> mFixedClass = new ConcurrentHashMap>(); 56 | 57 | /** 58 | * whether support AndFix 59 | */ 60 | private boolean mSupport = false; 61 | 62 | /** 63 | * security check 64 | */ 65 | private SecurityChecker mSecurityChecker; 66 | 67 | /** 68 | * optimize directory 69 | */ 70 | private File mOptDir; 71 | 72 | public AndFixManager(Context context) { 73 | mContext = context; 74 | mSupport = Compat.isSupport(); 75 | if (mSupport) { 76 | mSecurityChecker = new SecurityChecker(mContext); 77 | mOptDir = new File(mContext.getFilesDir(), DIR); 78 | if (!mOptDir.exists() && !mOptDir.mkdirs()) {// make directory fail 79 | mSupport = false; 80 | Log.e(TAG, "opt dir create error."); 81 | } else if (!mOptDir.isDirectory()) {// not directory 82 | mOptDir.delete(); 83 | mSupport = false; 84 | } 85 | } 86 | } 87 | 88 | /** 89 | * delete optimize file of patch file 90 | * 91 | * @param file 92 | * patch file 93 | */ 94 | public synchronized void removeOptFile(File file) { 95 | File optfile = new File(mOptDir, file.getName()); 96 | if (optfile.exists() && !optfile.delete()) { 97 | Log.e(TAG, optfile.getName() + " delete error."); 98 | } 99 | } 100 | 101 | /** 102 | * fix 103 | * 104 | * @param patchPath 105 | * patch path 106 | */ 107 | public synchronized void fix(String patchPath) { 108 | fix(new File(patchPath), mContext.getClassLoader(), null); 109 | } 110 | 111 | /** 112 | * fix 113 | * 114 | * @param file 115 | * patch file 116 | * @param classLoader 117 | * classloader of class that will be fixed 118 | * @param classes 119 | * classes will be fixed 120 | */ 121 | public synchronized void fix(File file, ClassLoader classLoader, 122 | List classes) { 123 | if (!mSupport) { 124 | return; 125 | } 126 | 127 | if (!mSecurityChecker.verifyApk(file)) {// security check fail 128 | return; 129 | } 130 | 131 | try { 132 | File optfile = new File(mOptDir, file.getName()); 133 | boolean saveFingerprint = true; 134 | if (optfile.exists()) { 135 | // need to verify fingerprint when the optimize file exist, 136 | // prevent someone attack on jailbreak device with 137 | // Vulnerability-Parasyte. 138 | // btw:exaggerated android Vulnerability-Parasyte 139 | // http://secauo.com/Exaggerated-Android-Vulnerability-Parasyte.html 140 | if (mSecurityChecker.verifyOpt(optfile)) { 141 | saveFingerprint = false; 142 | } else if (!optfile.delete()) { 143 | return; 144 | } 145 | } 146 | 147 | final DexFile dexFile = DexFile.loadDex(file.getAbsolutePath(), 148 | optfile.getAbsolutePath(), Context.MODE_PRIVATE); 149 | 150 | if (saveFingerprint) { 151 | mSecurityChecker.saveOptSig(optfile); 152 | } 153 | 154 | ClassLoader patchClassLoader = new ClassLoader(classLoader) { 155 | @Override 156 | protected Class findClass(String className) 157 | throws ClassNotFoundException { 158 | Class clazz = dexFile.loadClass(className, this); 159 | if (clazz == null 160 | && className.startsWith("com.alipay.euler.andfix")) { 161 | return Class.forName(className);// annotation’s class 162 | // not found 163 | } 164 | if (clazz == null) { 165 | throw new ClassNotFoundException(className); 166 | } 167 | return clazz; 168 | } 169 | }; 170 | Enumeration entrys = dexFile.entries(); 171 | Class clazz = null; 172 | while (entrys.hasMoreElements()) { 173 | String entry = entrys.nextElement(); 174 | if (classes != null && !classes.contains(entry)) { 175 | continue;// skip, not need fix 176 | } 177 | clazz = dexFile.loadClass(entry, patchClassLoader); 178 | if (clazz != null) { 179 | fixClass(clazz, classLoader); 180 | } 181 | } 182 | } catch (IOException e) { 183 | Log.e(TAG, "pacth", e); 184 | } 185 | } 186 | 187 | /** 188 | * fix class 189 | * 190 | * @param clazz 191 | * class 192 | */ 193 | private void fixClass(Class clazz, ClassLoader classLoader) { 194 | Method[] methods = clazz.getDeclaredMethods(); 195 | MethodReplace methodReplace; 196 | String clz; 197 | String meth; 198 | for (Method method : methods) { 199 | methodReplace = method.getAnnotation(MethodReplace.class); 200 | if (methodReplace == null) 201 | continue; 202 | clz = methodReplace.clazz(); 203 | meth = methodReplace.method(); 204 | if (!isEmpty(clz) && !isEmpty(meth)) { 205 | replaceMethod(classLoader, clz, meth, method); 206 | } 207 | } 208 | } 209 | 210 | /** 211 | * replace method 212 | * 213 | * @param classLoader classloader 214 | * @param clz class 215 | * @param meth name of target method 216 | * @param method source method 217 | */ 218 | private void replaceMethod(ClassLoader classLoader, String clz, 219 | String meth, Method method) { 220 | try { 221 | String key = clz + "@" + classLoader.toString(); 222 | Class clazz = mFixedClass.get(key); 223 | if (clazz == null) {// class not load 224 | Class clzz = classLoader.loadClass(clz); 225 | // initialize target class 226 | clazz = AndFix.initTargetClass(clzz); 227 | } 228 | if (clazz != null) {// initialize class OK 229 | mFixedClass.put(key, clazz); 230 | Method src = clazz.getDeclaredMethod(meth, 231 | method.getParameterTypes()); 232 | AndFix.addReplaceMethod(src, method); 233 | } 234 | } catch (Exception e) { 235 | Log.e(TAG, "replaceMethod", e); 236 | } 237 | } 238 | 239 | private static boolean isEmpty(String string) { 240 | return string == null || string.length() <= 0; 241 | } 242 | 243 | } 244 | -------------------------------------------------------------------------------- /src/com/alipay/euler/andfix/Compat.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright (c) 2015, alipay.com 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package com.alipay.euler.andfix; 19 | 20 | import java.lang.reflect.Method; 21 | 22 | import android.annotation.SuppressLint; 23 | 24 | /** 25 | * Compatibility 26 | * 27 | * @author sanping.li@alipay.com 28 | * 29 | */ 30 | public class Compat { 31 | public static boolean isChecked = false; 32 | public static boolean isSupport = false; 33 | 34 | /** 35 | * whether support on the device 36 | * 37 | * @return true if the device support AndFix 38 | */ 39 | public static synchronized boolean isSupport() { 40 | if (isChecked) 41 | return isSupport; 42 | 43 | isChecked = true; 44 | // not support alibaba's YunOs 45 | if (!isYunOS() && AndFix.setup() && isSupportSDKVersion()) { 46 | isSupport = true; 47 | } 48 | 49 | if (inBlackList()) { 50 | isSupport = false; 51 | } 52 | 53 | return isSupport; 54 | } 55 | 56 | @SuppressLint("DefaultLocale") 57 | private static boolean isYunOS() { 58 | String version = null; 59 | String vmName = null; 60 | try { 61 | Method m = Class.forName("android.os.SystemProperties").getMethod( 62 | "get", String.class); 63 | version = (String) m.invoke(null, "ro.yunos.version"); 64 | vmName = (String) m.invoke(null, "java.vm.name"); 65 | } catch (Exception e) { 66 | // nothing todo 67 | } 68 | if ((vmName != null && vmName.toLowerCase().contains("lemur")) 69 | || (version != null && version.trim().length() > 0)) { 70 | return true; 71 | } else { 72 | return false; 73 | } 74 | } 75 | 76 | // from android 2.3 to android 7.0 77 | private static boolean isSupportSDKVersion() { 78 | if (android.os.Build.VERSION.SDK_INT >= 8 79 | && android.os.Build.VERSION.SDK_INT <= 24) { 80 | return true; 81 | } 82 | return false; 83 | } 84 | 85 | private static boolean inBlackList() { 86 | return false; 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/com/alipay/euler/andfix/annotation/MethodReplace.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright (c) 2015, alipay.com 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package com.alipay.euler.andfix.annotation; 19 | 20 | import java.lang.annotation.ElementType; 21 | import java.lang.annotation.Retention; 22 | import java.lang.annotation.RetentionPolicy; 23 | import java.lang.annotation.Target; 24 | 25 | /** 26 | * Annotation for method 27 | * 28 | * @author sanping.li@alipay.com 29 | * 30 | */ 31 | @Target(ElementType.METHOD) 32 | @Retention(RetentionPolicy.RUNTIME) 33 | public @interface MethodReplace { 34 | String clazz(); 35 | 36 | String method(); 37 | } 38 | -------------------------------------------------------------------------------- /src/com/alipay/euler/andfix/patch/Patch.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright (c) 2015, alipay.com 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package com.alipay.euler.andfix.patch; 19 | 20 | import java.io.File; 21 | import java.io.IOException; 22 | import java.io.InputStream; 23 | import java.util.Arrays; 24 | import java.util.Date; 25 | import java.util.HashMap; 26 | import java.util.Iterator; 27 | import java.util.List; 28 | import java.util.Map; 29 | import java.util.Set; 30 | import java.util.jar.Attributes; 31 | import java.util.jar.JarEntry; 32 | import java.util.jar.JarFile; 33 | import java.util.jar.Manifest; 34 | 35 | /** 36 | * patch model 37 | * 38 | * @author sanping.li@alipay.com 39 | * 40 | */ 41 | public class Patch implements Comparable { 42 | private static final String ENTRY_NAME = "META-INF/PATCH.MF"; 43 | private static final String CLASSES = "-Classes"; 44 | private static final String PATCH_CLASSES = "Patch-Classes"; 45 | private static final String CREATED_TIME = "Created-Time"; 46 | private static final String PATCH_NAME = "Patch-Name"; 47 | 48 | /** 49 | * patch file 50 | */ 51 | private final File mFile; 52 | /** 53 | * name 54 | */ 55 | private String mName; 56 | /** 57 | * create time 58 | */ 59 | private Date mTime; 60 | /** 61 | * classes of patch 62 | */ 63 | private Map> mClassesMap; 64 | 65 | public Patch(File file) throws IOException { 66 | mFile = file; 67 | init(); 68 | } 69 | 70 | @SuppressWarnings("deprecation") 71 | private void init() throws IOException { 72 | JarFile jarFile = null; 73 | InputStream inputStream = null; 74 | try { 75 | jarFile = new JarFile(mFile); 76 | JarEntry entry = jarFile.getJarEntry(ENTRY_NAME); 77 | inputStream = jarFile.getInputStream(entry); 78 | Manifest manifest = new Manifest(inputStream); 79 | Attributes main = manifest.getMainAttributes(); 80 | mName = main.getValue(PATCH_NAME); 81 | mTime = new Date(main.getValue(CREATED_TIME)); 82 | 83 | mClassesMap = new HashMap>(); 84 | Attributes.Name attrName; 85 | String name; 86 | List strings; 87 | for (Iterator it = main.keySet().iterator(); it.hasNext();) { 88 | attrName = (Attributes.Name) it.next(); 89 | name = attrName.toString(); 90 | if (name.endsWith(CLASSES)) { 91 | strings = Arrays.asList(main.getValue(attrName).split(",")); 92 | if (name.equalsIgnoreCase(PATCH_CLASSES)) { 93 | mClassesMap.put(mName, strings); 94 | } else { 95 | mClassesMap.put( 96 | name.trim().substring(0, name.length() - 8),// remove 97 | // "-Classes" 98 | strings); 99 | } 100 | } 101 | } 102 | } finally { 103 | if (jarFile != null) { 104 | jarFile.close(); 105 | } 106 | if (inputStream != null) { 107 | inputStream.close(); 108 | } 109 | } 110 | 111 | } 112 | 113 | public String getName() { 114 | return mName; 115 | } 116 | 117 | public File getFile() { 118 | return mFile; 119 | } 120 | 121 | public Set getPatchNames() { 122 | return mClassesMap.keySet(); 123 | } 124 | 125 | public List getClasses(String patchName) { 126 | return mClassesMap.get(patchName); 127 | } 128 | 129 | public Date getTime() { 130 | return mTime; 131 | } 132 | 133 | @Override 134 | public int compareTo(Patch another) { 135 | return mTime.compareTo(another.getTime()); 136 | } 137 | 138 | } 139 | -------------------------------------------------------------------------------- /src/com/alipay/euler/andfix/patch/PatchManager.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright (c) 2015, alipay.com 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package com.alipay.euler.andfix.patch; 19 | 20 | import java.io.File; 21 | import java.io.FileNotFoundException; 22 | import java.io.IOException; 23 | import java.util.List; 24 | import java.util.Map; 25 | import java.util.Set; 26 | import java.util.SortedSet; 27 | import java.util.concurrent.ConcurrentHashMap; 28 | import java.util.concurrent.ConcurrentSkipListSet; 29 | 30 | import android.content.Context; 31 | import android.content.SharedPreferences; 32 | import android.util.Log; 33 | 34 | import com.alipay.euler.andfix.AndFixManager; 35 | import com.alipay.euler.andfix.util.FileUtil; 36 | 37 | /** 38 | * patch manager 39 | * 40 | * @author sanping.li@alipay.com 41 | * 42 | */ 43 | public class PatchManager { 44 | private static final String TAG = "PatchManager"; 45 | // patch extension 46 | private static final String SUFFIX = ".apatch"; 47 | private static final String DIR = "apatch"; 48 | private static final String SP_NAME = "_andfix_"; 49 | private static final String SP_VERSION = "version"; 50 | 51 | /** 52 | * context 53 | */ 54 | private final Context mContext; 55 | /** 56 | * AndFix manager 57 | */ 58 | private final AndFixManager mAndFixManager; 59 | /** 60 | * patch directory 61 | */ 62 | private final File mPatchDir; 63 | /** 64 | * patchs 65 | */ 66 | private final SortedSet mPatchs; 67 | /** 68 | * classloaders 69 | */ 70 | private final Map mLoaders; 71 | 72 | /** 73 | * @param context 74 | * context 75 | */ 76 | public PatchManager(Context context) { 77 | mContext = context; 78 | mAndFixManager = new AndFixManager(mContext); 79 | mPatchDir = new File(mContext.getFilesDir(), DIR); 80 | mPatchs = new ConcurrentSkipListSet(); 81 | mLoaders = new ConcurrentHashMap(); 82 | } 83 | 84 | /** 85 | * initialize 86 | * 87 | * @param appVersion 88 | * App version 89 | */ 90 | public void init(String appVersion) { 91 | if (!mPatchDir.exists() && !mPatchDir.mkdirs()) {// make directory fail 92 | Log.e(TAG, "patch dir create error."); 93 | return; 94 | } else if (!mPatchDir.isDirectory()) {// not directory 95 | mPatchDir.delete(); 96 | return; 97 | } 98 | SharedPreferences sp = mContext.getSharedPreferences(SP_NAME, 99 | Context.MODE_PRIVATE); 100 | String ver = sp.getString(SP_VERSION, null); 101 | if (ver == null || !ver.equalsIgnoreCase(appVersion)) { 102 | cleanPatch(); 103 | sp.edit().putString(SP_VERSION, appVersion).commit(); 104 | } else { 105 | initPatchs(); 106 | } 107 | } 108 | 109 | private void initPatchs() { 110 | File[] files = mPatchDir.listFiles(); 111 | for (File file : files) { 112 | addPatch(file); 113 | } 114 | } 115 | 116 | /** 117 | * add patch file 118 | * 119 | * @param file 120 | * @return patch 121 | */ 122 | private Patch addPatch(File file) { 123 | Patch patch = null; 124 | if (file.getName().endsWith(SUFFIX)) { 125 | try { 126 | patch = new Patch(file); 127 | mPatchs.add(patch); 128 | } catch (IOException e) { 129 | Log.e(TAG, "addPatch", e); 130 | } 131 | } 132 | return patch; 133 | } 134 | 135 | private void cleanPatch() { 136 | File[] files = mPatchDir.listFiles(); 137 | for (File file : files) { 138 | mAndFixManager.removeOptFile(file); 139 | if (!FileUtil.deleteFile(file)) { 140 | Log.e(TAG, file.getName() + " delete error."); 141 | } 142 | } 143 | } 144 | 145 | /** 146 | * add patch at runtime 147 | * 148 | * @param path 149 | * patch path 150 | * @throws IOException 151 | */ 152 | public void addPatch(String path) throws IOException { 153 | File src = new File(path); 154 | File dest = new File(mPatchDir, src.getName()); 155 | if(!src.exists()){ 156 | throw new FileNotFoundException(path); 157 | } 158 | if (dest.exists()) { 159 | Log.d(TAG, "patch [" + path + "] has be loaded."); 160 | return; 161 | } 162 | FileUtil.copyFile(src, dest);// copy to patch's directory 163 | Patch patch = addPatch(dest); 164 | if (patch != null) { 165 | loadPatch(patch); 166 | } 167 | } 168 | 169 | /** 170 | * remove all patchs 171 | */ 172 | public void removeAllPatch() { 173 | cleanPatch(); 174 | SharedPreferences sp = mContext.getSharedPreferences(SP_NAME, 175 | Context.MODE_PRIVATE); 176 | sp.edit().clear().commit(); 177 | } 178 | 179 | /** 180 | * load patch,call when plugin be loaded. used for plugin architecture.
181 | * 182 | * need name and classloader of the plugin 183 | * 184 | * @param patchName 185 | * patch name 186 | * @param classLoader 187 | * classloader 188 | */ 189 | public void loadPatch(String patchName, ClassLoader classLoader) { 190 | mLoaders.put(patchName, classLoader); 191 | Set patchNames; 192 | List classes; 193 | for (Patch patch : mPatchs) { 194 | patchNames = patch.getPatchNames(); 195 | if (patchNames.contains(patchName)) { 196 | classes = patch.getClasses(patchName); 197 | mAndFixManager.fix(patch.getFile(), classLoader, classes); 198 | } 199 | } 200 | } 201 | 202 | /** 203 | * load patch,call when application start 204 | * 205 | */ 206 | public void loadPatch() { 207 | mLoaders.put("*", mContext.getClassLoader());// wildcard 208 | Set patchNames; 209 | List classes; 210 | for (Patch patch : mPatchs) { 211 | patchNames = patch.getPatchNames(); 212 | for (String patchName : patchNames) { 213 | classes = patch.getClasses(patchName); 214 | mAndFixManager.fix(patch.getFile(), mContext.getClassLoader(), 215 | classes); 216 | } 217 | } 218 | } 219 | 220 | /** 221 | * load specific patch 222 | * 223 | * @param patch 224 | * patch 225 | */ 226 | private void loadPatch(Patch patch) { 227 | Set patchNames = patch.getPatchNames(); 228 | ClassLoader cl; 229 | List classes; 230 | for (String patchName : patchNames) { 231 | if (mLoaders.containsKey("*")) { 232 | cl = mContext.getClassLoader(); 233 | } else { 234 | cl = mLoaders.get(patchName); 235 | } 236 | if (cl != null) { 237 | classes = patch.getClasses(patchName); 238 | mAndFixManager.fix(patch.getFile(), cl, classes); 239 | } 240 | } 241 | } 242 | 243 | } 244 | -------------------------------------------------------------------------------- /src/com/alipay/euler/andfix/security/SecurityChecker.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright (c) 2015, alipay.com 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package com.alipay.euler.andfix.security; 19 | 20 | import java.io.ByteArrayInputStream; 21 | import java.io.File; 22 | import java.io.FileInputStream; 23 | import java.io.IOException; 24 | import java.io.InputStream; 25 | import java.math.BigInteger; 26 | import java.security.MessageDigest; 27 | import java.security.PublicKey; 28 | import java.security.cert.Certificate; 29 | import java.security.cert.CertificateException; 30 | import java.security.cert.CertificateFactory; 31 | import java.security.cert.X509Certificate; 32 | import java.util.jar.JarEntry; 33 | import java.util.jar.JarFile; 34 | 35 | import javax.security.auth.x500.X500Principal; 36 | 37 | import android.content.Context; 38 | import android.content.SharedPreferences; 39 | import android.content.SharedPreferences.Editor; 40 | import android.content.pm.PackageInfo; 41 | import android.content.pm.PackageManager; 42 | import android.content.pm.PackageManager.NameNotFoundException; 43 | import android.text.TextUtils; 44 | import android.util.Log; 45 | 46 | /** 47 | * security check 48 | * 49 | * @author sanping.li@alipay.com 50 | * 51 | */ 52 | public class SecurityChecker { 53 | private static final String TAG = "SecurityChecker"; 54 | 55 | private static final String SP_NAME = "_andfix_"; 56 | private static final String SP_MD5 = "-md5"; 57 | private static final String CLASSES_DEX = "classes.dex"; 58 | 59 | private static final X500Principal DEBUG_DN = new X500Principal( 60 | "CN=Android Debug,O=Android,C=US"); 61 | 62 | private final Context mContext; 63 | /** 64 | * host publickey 65 | */ 66 | private PublicKey mPublicKey; 67 | /** 68 | * host debuggable 69 | */ 70 | private boolean mDebuggable; 71 | 72 | public SecurityChecker(Context context) { 73 | mContext = context; 74 | init(mContext); 75 | } 76 | 77 | /** 78 | * @param path 79 | * Dex file 80 | * @return true if verify fingerprint success 81 | */ 82 | public boolean verifyOpt(File file) { 83 | String fingerprint = getFileMD5(file); 84 | String saved = getFingerprint(file.getName()); 85 | if (fingerprint != null && TextUtils.equals(fingerprint, saved)) { 86 | return true; 87 | } 88 | return false; 89 | } 90 | 91 | /** 92 | * @param path 93 | * Dex file 94 | */ 95 | public void saveOptSig(File file) { 96 | String fingerprint = getFileMD5(file); 97 | saveFingerprint(file.getName(), fingerprint); 98 | } 99 | 100 | /** 101 | * @param path 102 | * Apk file 103 | * @return true if verify apk success 104 | */ 105 | public boolean verifyApk(File path) { 106 | if (mDebuggable) { 107 | Log.d(TAG, "mDebuggable = true"); 108 | return true; 109 | } 110 | 111 | JarFile jarFile = null; 112 | try { 113 | jarFile = new JarFile(path); 114 | 115 | JarEntry jarEntry = jarFile.getJarEntry(CLASSES_DEX); 116 | if (null == jarEntry) {// no code 117 | return false; 118 | } 119 | loadDigestes(jarFile, jarEntry); 120 | Certificate[] certs = jarEntry.getCertificates(); 121 | if (certs == null) { 122 | return false; 123 | } 124 | return check(path, certs); 125 | } catch (IOException e) { 126 | Log.e(TAG, path.getAbsolutePath(), e); 127 | return false; 128 | } finally { 129 | try { 130 | if (jarFile != null) { 131 | jarFile.close(); 132 | } 133 | } catch (IOException e) { 134 | Log.e(TAG, path.getAbsolutePath(), e); 135 | } 136 | } 137 | } 138 | 139 | private void loadDigestes(JarFile jarFile, JarEntry je) throws IOException { 140 | InputStream is = null; 141 | try { 142 | is = jarFile.getInputStream(je); 143 | byte[] bytes = new byte[8192]; 144 | while (is.read(bytes) > 0) { 145 | } 146 | } finally { 147 | if (is != null) { 148 | is.close(); 149 | } 150 | } 151 | } 152 | 153 | // verify the signature of the Apk 154 | private boolean check(File path, Certificate[] certs) { 155 | if (certs.length > 0) { 156 | for (int i = certs.length - 1; i >= 0; i--) { 157 | try { 158 | certs[i].verify(mPublicKey); 159 | return true; 160 | } catch (Exception e) { 161 | Log.e(TAG, path.getAbsolutePath(), e); 162 | } 163 | } 164 | } 165 | return false; 166 | } 167 | 168 | private String getFileMD5(File file) { 169 | if (!file.isFile()) { 170 | return null; 171 | } 172 | MessageDigest digest = null; 173 | FileInputStream in = null; 174 | byte buffer[] = new byte[8192]; 175 | int len; 176 | try { 177 | digest = MessageDigest.getInstance("MD5"); 178 | in = new FileInputStream(file); 179 | while ((len = in.read(buffer)) != -1) { 180 | digest.update(buffer, 0, len); 181 | } 182 | } catch (Exception e) { 183 | Log.e(TAG, "getFileMD5", e); 184 | return null; 185 | } finally { 186 | try { 187 | if (in != null) 188 | in.close(); 189 | } catch (IOException e) { 190 | Log.e(TAG, "getFileMD5", e); 191 | } 192 | } 193 | BigInteger bigInt = new BigInteger(digest.digest()); 194 | return bigInt.toString(); 195 | } 196 | 197 | // md5 as fingerprint 198 | private void saveFingerprint(String fileName, String md5) { 199 | SharedPreferences sharedPreferences = mContext.getSharedPreferences( 200 | SP_NAME, Context.MODE_PRIVATE); 201 | Editor editor = sharedPreferences.edit(); 202 | editor.putString(fileName + SP_MD5, md5); 203 | editor.commit(); 204 | } 205 | 206 | private String getFingerprint(String fileName) { 207 | SharedPreferences sharedPreferences = mContext.getSharedPreferences( 208 | SP_NAME, Context.MODE_PRIVATE); 209 | return sharedPreferences.getString(fileName + SP_MD5, null); 210 | } 211 | 212 | // initialize,and check debuggable 213 | private void init(Context context) { 214 | try { 215 | PackageManager pm = context.getPackageManager(); 216 | String packageName = context.getPackageName(); 217 | 218 | PackageInfo packageInfo = pm.getPackageInfo(packageName, 219 | PackageManager.GET_SIGNATURES); 220 | CertificateFactory certFactory = CertificateFactory 221 | .getInstance("X.509"); 222 | ByteArrayInputStream stream = new ByteArrayInputStream( 223 | packageInfo.signatures[0].toByteArray()); 224 | X509Certificate cert = (X509Certificate) certFactory 225 | .generateCertificate(stream); 226 | mDebuggable = cert.getSubjectX500Principal().equals(DEBUG_DN); 227 | mPublicKey = cert.getPublicKey(); 228 | } catch (NameNotFoundException e) { 229 | Log.e(TAG, "init", e); 230 | } catch (CertificateException e) { 231 | Log.e(TAG, "init", e); 232 | } 233 | } 234 | 235 | } 236 | -------------------------------------------------------------------------------- /src/com/alipay/euler/andfix/util/FileUtil.java: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright (c) 2015, alipay.com 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package com.alipay.euler.andfix.util; 19 | 20 | import java.io.File; 21 | import java.io.FileInputStream; 22 | import java.io.FileOutputStream; 23 | import java.io.IOException; 24 | import java.nio.channels.FileChannel; 25 | 26 | /** 27 | * file utility 28 | * 29 | * @author sanping.li@alipay.com 30 | * 31 | */ 32 | public class FileUtil { 33 | 34 | /** 35 | * 36 | * copy file 37 | * 38 | * @param src 39 | * source file 40 | * @param dest 41 | * target file 42 | * @throws IOException 43 | */ 44 | public static void copyFile(File src, File dest) throws IOException { 45 | FileChannel inChannel = null; 46 | FileChannel outChannel = null; 47 | try { 48 | if (!dest.exists()) { 49 | dest.createNewFile(); 50 | } 51 | inChannel = new FileInputStream(src).getChannel(); 52 | outChannel = new FileOutputStream(dest).getChannel(); 53 | inChannel.transferTo(0, inChannel.size(), outChannel); 54 | } finally { 55 | if (inChannel != null) { 56 | inChannel.close(); 57 | } 58 | if (outChannel != null) { 59 | outChannel.close(); 60 | } 61 | } 62 | } 63 | 64 | /** 65 | * delete file 66 | * 67 | * @param file 68 | * file 69 | * @return true if delete success 70 | */ 71 | public static boolean deleteFile(File file) { 72 | if (!file.exists()) { 73 | return true; 74 | } 75 | if (file.isDirectory()) { 76 | File[] files = file.listFiles(); 77 | for (File f : files) { 78 | deleteFile(f); 79 | } 80 | } 81 | return file.delete(); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /tools/apkpatch-1.0.3.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alibaba/AndFix/0351a4bc38a7d30bc61a6d3e74777d4eff4ad5e9/tools/apkpatch-1.0.3.zip --------------------------------------------------------------------------------