Showing preview only (389K chars total). Download the full file or copy to clipboard to get everything.
Repository: tiann/epic
Branch: master
Commit: c67d0d3e3769
Files: 137
Total size: 349.2 KB
Directory structure:
gitextract_6vz_tr23/
├── .github/
│ ├── FUNDING.yml
│ └── workflows/
│ └── android.yml
├── .gitignore
├── LICENSE
├── README.md
├── README_cn.md
├── app/
│ ├── .gitignore
│ ├── build.gradle
│ ├── proguard-rules.pro
│ └── src/
│ ├── androidTest/
│ │ └── java/
│ │ └── me/
│ │ └── weishu/
│ │ └── epic/
│ │ └── ExampleInstrumentedTest.java
│ ├── main/
│ │ ├── AndroidManifest.xml
│ │ ├── java/
│ │ │ └── me/
│ │ │ └── weishu/
│ │ │ └── epic/
│ │ │ └── samples/
│ │ │ ├── MainActivity.java
│ │ │ ├── MainApplication.java
│ │ │ └── tests/
│ │ │ ├── CallingConventationTest.java
│ │ │ ├── LogMethodHook.java
│ │ │ ├── TestCase.java
│ │ │ ├── TestManager.java
│ │ │ ├── TestSuite.java
│ │ │ ├── arguments/
│ │ │ │ ├── AbsArgStaticCase.java
│ │ │ │ ├── ArgStatic0.java
│ │ │ │ ├── ArgStatic4.java
│ │ │ │ ├── ArgStatic44.java
│ │ │ │ ├── ArgStatic444.java
│ │ │ │ ├── ArgStatic4444.java
│ │ │ │ ├── ArgStatic4448.java
│ │ │ │ ├── ArgStatic448.java
│ │ │ │ ├── ArgStatic4484.java
│ │ │ │ ├── ArgStatic4488.java
│ │ │ │ ├── ArgStatic48.java
│ │ │ │ ├── ArgStatic484.java
│ │ │ │ ├── ArgStatic4844.java
│ │ │ │ ├── ArgStatic4848.java
│ │ │ │ ├── ArgStatic488.java
│ │ │ │ ├── ArgStatic4884.java
│ │ │ │ ├── ArgStatic4888.java
│ │ │ │ ├── ArgStatic8.java
│ │ │ │ ├── ArgStatic84.java
│ │ │ │ ├── ArgStatic844.java
│ │ │ │ ├── ArgStatic8444.java
│ │ │ │ ├── ArgStatic8448.java
│ │ │ │ ├── ArgStatic848.java
│ │ │ │ ├── ArgStatic8484.java
│ │ │ │ ├── ArgStatic8488.java
│ │ │ │ ├── ArgStatic88.java
│ │ │ │ ├── ArgStatic884.java
│ │ │ │ ├── ArgStatic8844.java
│ │ │ │ ├── ArgStatic8848.java
│ │ │ │ ├── ArgStatic888.java
│ │ │ │ ├── ArgStatic8884.java
│ │ │ │ ├── ArgStatic8888.java
│ │ │ │ └── ArgumentTarget.java
│ │ │ ├── custom/
│ │ │ │ ├── Case.java
│ │ │ │ ├── Case1.java
│ │ │ │ ├── Case10_Default_Constructor.java
│ │ │ │ ├── Case11_SuspendAll.java
│ │ │ │ ├── Case12_MultiCallback.java
│ │ │ │ ├── Case13_FastNative.java
│ │ │ │ ├── Case14_GC.java
│ │ │ │ ├── Case15_StopJit.java
│ │ │ │ ├── Case16_SameEntry.java
│ │ │ │ ├── Case17_SameMethod.java
│ │ │ │ ├── Case18_returnConst.java
│ │ │ │ ├── Case2.java
│ │ │ │ ├── Case3.java
│ │ │ │ ├── Case4.java
│ │ │ │ ├── Case5.java
│ │ │ │ ├── Case6.java
│ │ │ │ ├── Case7.java
│ │ │ │ ├── Case8_Activity_onCreate.java
│ │ │ │ ├── Case9_ThreadMonitor.java
│ │ │ │ ├── CaseManager.java
│ │ │ │ └── Target.java
│ │ │ ├── invoketype/
│ │ │ │ ├── InvokeConstructor.java
│ │ │ │ └── InvokeTypeTarget.java
│ │ │ └── returntype/
│ │ │ ├── BooleanType.java
│ │ │ ├── ByteType.java
│ │ │ ├── CharType.java
│ │ │ ├── CustomType.java
│ │ │ ├── DoubleType.java
│ │ │ ├── FloatType.java
│ │ │ ├── IntType.java
│ │ │ ├── LongType.java
│ │ │ ├── ReturnTypeTarget.java
│ │ │ ├── ShortType.java
│ │ │ ├── StringArrayType.java
│ │ │ ├── StringType.java
│ │ │ └── VoidType.java
│ │ └── res/
│ │ ├── layout/
│ │ │ ├── activity_main.xml
│ │ │ ├── child_layout.xml
│ │ │ └── parent_layout.xml
│ │ └── values/
│ │ ├── colors.xml
│ │ ├── strings.xml
│ │ └── styles.xml
│ └── test/
│ └── java/
│ └── me/
│ └── weishu/
│ └── epic/
│ └── ExampleUnitTest.java
├── build.gradle
├── gradle/
│ └── wrapper/
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradle.properties
├── gradlew
├── gradlew.bat
├── library/
│ ├── .gitignore
│ ├── CMakeCache.txt
│ ├── build.gradle
│ ├── proguard-rules.pro
│ └── src/
│ └── main/
│ ├── AndroidManifest.xml
│ ├── cpp/
│ │ ├── .gitignore
│ │ ├── CMakeLists.txt
│ │ ├── art.cpp
│ │ ├── art.h
│ │ ├── build_with_cmake
│ │ ├── epic.cpp
│ │ ├── fake_dlfcn.cpp
│ │ └── fake_dlfcn.h
│ ├── java/
│ │ ├── com/
│ │ │ └── taobao/
│ │ │ └── android/
│ │ │ └── dexposed/
│ │ │ ├── ClassUtils.java
│ │ │ ├── DeviceCheck.java
│ │ │ └── utility/
│ │ │ ├── Debug.java
│ │ │ ├── Logger.java
│ │ │ ├── NeverCalled.java
│ │ │ ├── NougatPolicy.java
│ │ │ ├── Platform.java
│ │ │ ├── Runtime.java
│ │ │ └── Unsafe.java
│ │ ├── de/
│ │ │ └── robv/
│ │ │ └── android/
│ │ │ └── xposed/
│ │ │ └── DexposedBridge.java
│ │ └── me/
│ │ └── weishu/
│ │ └── epic/
│ │ └── art/
│ │ ├── Epic.java
│ │ ├── EpicNative.java
│ │ ├── Trampoline.java
│ │ ├── arch/
│ │ │ ├── Arm64.java
│ │ │ ├── Arm64_2.java
│ │ │ ├── ShellCode.java
│ │ │ └── Thumb2.java
│ │ ├── entry/
│ │ │ ├── Entry.java
│ │ │ ├── Entry64.java
│ │ │ └── Entry64_2.java
│ │ └── method/
│ │ ├── ArtMethod.java
│ │ └── Offset.java
│ └── res/
│ └── values/
│ └── strings.xml
└── settings.gradle
================================================
FILE CONTENTS
================================================
================================================
FILE: .github/FUNDING.yml
================================================
# These are supported funding model platforms
github: # replace
patreon: weishu
open_collective: # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
custom: http://paypal.me/virtualxposed
================================================
FILE: .github/workflows/android.yml
================================================
name: Android CI
on: [push]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: set up JDK 1.8
uses: actions/setup-java@v1
with:
java-version: 1.8
- name: Build with Gradle
run: ./gradlew build
================================================
FILE: .gitignore
================================================
*.iml
.gradle
/local.properties
/.idea/workspace.xml
/.idea/libraries
.DS_Store
/build
/captures
.externalNativeBuild
.idea
================================================
FILE: LICENSE
================================================
Original work Copyright (c) 2005-2008, The Android Open Source Project
Modified work Copyright (c) 2013, rovo89 and Tungstwenty
Modified work Copyright (c) 2015, Alibaba Mobile Infrastructure (Android) Team
Modified work Copyright (c) 2017, weishu
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
================================================
FILE: README.md
================================================
[ ](https://bintray.com/twsxtd/maven/epic/_latestVersion)
[](https://gitter.im/android-hacker/epic?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[中文文档入口](README_cn.md "中文")
What is it?
-----------
Epic is the continuation of [Dexposed](https://github.com/alibaba/dexposed) on ART (Supports 5.0 ~ 11).
> Dexposed is a powerful yet non-invasive runtime [AOP (Aspect-oriented Programming)](http://en.wikipedia.org/wiki/Aspect-oriented_programming) framework
for Android app development, based on the work of open-source [Xposed](https://github.com/rovo89/Xposed) [framework](https://github.com/rovo89/XposedBridge) project.
>
> The AOP of Dexposed is implemented purely non-invasive, without any annotation processor,
weaver or bytecode rewriter. The integration is as simple as loading a small JNI library
in just one line of code at the initialization phase of your app.
>
> Not only the code of your app, but also the code of Android framework that running in your
app process can be hooked.
Epic keeps the same API and all capability of Dexposed, you can do anything which is supported by Dexposed.
Typical use-cases
-----------------
* Classic AOP programming
* Instrumentation (for testing, performance monitoring and etc.)
* Security audit (sensitive api check,Smash shell)
* Just for fun :)
Integration
-----------
Directly add epic aar to your project as compile libraries, Gradle dependency like following(jitpack):
```groovy
dependencies {
compile 'com.github.tiann:epic:0.11.2'
}
```
Everything is ready.
Basic usage
-----------
There are three injection points for a given method: *before*, *after*, *origin*.
Example 1: monitor the creation and destroy of java thread
```java
class ThreadMethodHook extends XC_MethodHook{
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
super.beforeHookedMethod(param);
Thread t = (Thread) param.thisObject;
Log.i(TAG, "thread:" + t + ", started..");
}
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
super.afterHookedMethod(param);
Thread t = (Thread) param.thisObject;
Log.i(TAG, "thread:" + t + ", exit..");
}
}
DexposedBridge.hookAllConstructors(Thread.class, new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
super.afterHookedMethod(param);
Thread thread = (Thread) param.thisObject;
Class<?> clazz = thread.getClass();
if (clazz != Thread.class) {
Log.d(TAG, "found class extend Thread:" + clazz);
DexposedBridge.findAndHookMethod(clazz, "run", new ThreadMethodHook());
}
Log.d(TAG, "Thread: " + thread.getName() + " class:" + thread.getClass() + " is created.");
}
});
DexposedBridge.findAndHookMethod(Thread.class, "run", new ThreadMethodHook());
```
Example 2: Intercept the dex loading behavior
```java
DexposedBridge.findAndHookMethod(DexFile.class, "loadDex", String.class, String.class, int.class, new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
super.beforeHookedMethod(param);
String dex = (String) param.args[0];
String odex = (String) param.args[1];
Log.i(TAG, "load dex, input:" + dex + ", output:" + odex);
}
});
```
Checkout the `sample` project to find out more.
Support
----------
Epic supports ART thumb2 and arm64 architecture from Android 5.0 ~ 11. arm32, x86, x86_64 and mips are not supported now (Thus it cannot work on android emulator).
Known Issues
-------------
1. Short method (instruction less 8 bytes on thumb2 or less 16bytes in ARM64) are not supported.
2. Fully inline methods are not supported.
Contribute
----------
We are open to constructive contributions from the community, especially pull request
and quality bug report. **Currently, the implementation for ART is not proved in large scale, we value your help to test or improve the implementation.**
You can clone this project, build and install the sample app, just make some click in your device, if some bugs/crash occurs, please file an issue or a pull request, I would appreciate it :)
Thanks
-------
1. [Dexposed](https://github.com/alibaba/dexposed)
2. [Xposed](http://repo.xposed.info/module/de.robv.android.xposed.installer)
3. [mar-v-in/ArtHook](https://github.com/mar-v-in/ArtHook)
4. [Nougat_dlfunctions](https://github.com/avs333/Nougat_dlfunctions.git)
Contact me
----------
twsxtd@gmail.com
[Join discussion](https://gitter.im/android-hacker/epic?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
================================================
FILE: README_cn.md
================================================
## 简介
Epic 是一个在虚拟机层面、以 Java Method 为粒度的 **运行时** AOP Hook 框架。简单来说,Epic 就是 ART 上的 [Dexposed](https://github.com/alibaba/dexposed)(支持 Android 5.0 ~ 11)。它可以拦截本进程内部几乎任意的 Java 方法调用,可用于实现 AOP 编程、运行时插桩、性能分析、安全审计等。
Epic 被 [VirtualXposed](https://github.com/android-hacker/VirtualXposed) 以及 [太极](https://www.coolapk.com/apk/me.weishu.exp) 使用,用来实现非 Root 场景下的 Xposed 功能,已经经过了相当广泛的验证。
关于 Epic 的实现原理,可以参考 [本文](http://weishu.me/2017/11/23/dexposed-on-art/)。
## 使用
### 添加依赖
在你项目的 build.gradle 中添加如下依赖(jitpack 仓库):
```groovy
dependencies {
compile 'com.github.tiann:epic:0.11.2'
}
```
然后就可以使用了。
### 几个例子
1. 监控 Java 线程的创建和销毁:
```java
class ThreadMethodHook extends XC_MethodHook{
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
super.beforeHookedMethod(param);
Thread t = (Thread) param.thisObject;
Log.i(TAG, "thread:" + t + ", started..");
}
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
super.afterHookedMethod(param);
Thread t = (Thread) param.thisObject;
Log.i(TAG, "thread:" + t + ", exit..");
}
}
DexposedBridge.hookAllConstructors(Thread.class, new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
super.afterHookedMethod(param);
Thread thread = (Thread) param.thisObject;
Class<?> clazz = thread.getClass();
if (clazz != Thread.class) {
Log.d(TAG, "found class extend Thread:" + clazz);
DexposedBridge.findAndHookMethod(clazz, "run", new ThreadMethodHook());
}
Log.d(TAG, "Thread: " + thread.getName() + " class:" + thread.getClass() + " is created.");
}
});
DexposedBridge.findAndHookMethod(Thread.class, "run", new ThreadMethodHook());
```
以上代码拦截了 `Thread` 类以及 `Thread` 类所有子类的 `run`方法,在 `run` 方法开始执行和退出的时候进行拦截,就可以知道进程内部所有 Java 线程创建和销毁的时机;更进一步,你可以结合 Systrace 等工具,来生成整个过程的执行流程图,比如:
<img src="http://7xp3xc.com1.z0.glb.clouddn.com/201601/1511840542774.png" width="480"/>
2. 监控 dex 文件的加载:
```java
DexposedBridge.findAndHookMethod(DexFile.class, "loadDex", String.class, String.class, int.class, new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
super.beforeHookedMethod(param);
String dex = (String) param.args[0];
String odex = (String) param.args[1];
Log.i(TAG, "load dex, input:" + dex + ", output:" + odex);
}
});
```
## 支持情况
目前 Epic 支持 Android 5.0 ~ 11 的 Thumb-2/ARM64 指令集,arm32/x86/x86_64/mips/mips64 不支持。本项目被 [VirtualXposed](https://github.com/android-hacker/VirtualXposed) 和 [太极](http://taichi.cool) 以及大量企业级用户使用,经过了数千万用户的验证,已经被证明非常稳定。目前,手机 QQ 已经在产品中使用 Epic。
## 已知问题
1. 受限于 inline hook 本身,短方法 (Thumb-2 下指令小于 8 个字节,ARM64 小于 16 字节) 无法支持。
2. 被完全内联的方法不支持。
## 致谢
1. [Dexposed](https://github.com/alibaba/dexposed)
2. [Xposed](http://repo.xposed.info/module/de.robv.android.xposed.installer)
3. [mar-v-in/ArtHook](https://github.com/mar-v-in/ArtHook)
4. [Nougat_dlfunctions](https://github.com/avs333/Nougat_dlfunctions.git)
## 联系我
twsxtd@gmail.com
================================================
FILE: app/.gitignore
================================================
/build
================================================
FILE: app/build.gradle
================================================
apply plugin: 'com.android.application'
android {
compileSdkVersion 30
defaultConfig {
applicationId "me.weishu.epic.samples"
minSdkVersion 21
targetSdkVersion 30
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
externalNativeBuild {
ndkBuild {
abiFilters "armeabi-v7a", "x86"
}
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
sourceSets {
main {
jniLibs.srcDirs = ['libs']
}
}
lintOptions {
abortOnError false
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation project(":library")
implementation 'com.qmuiteam:qmui:1.0.4'
}
================================================
FILE: app/proguard-rules.pro
================================================
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in /Users/weishu/Library/Android/sdk/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# Add any project specific keep options here:
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
================================================
FILE: app/src/androidTest/java/me/weishu/epic/ExampleInstrumentedTest.java
================================================
//package me.weishu.epic;
//
//import android.content.Context;
//import android.support.test.InstrumentationRegistry;
//import android.support.test.runner.AndroidJUnit4;
//
//import org.junit.Test;
//import org.junit.runner.RunWith;
//
//import static junit.framework.Assert.assertEquals;
//import static org.junit.Assert.*;
//
///**
// * Instrumentation test, which will execute on an Android device.
// *
// * @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
// */
//@RunWith(AndroidJUnit4.class)
//public class ExampleInstrumentedTest {
// @Test
// public void useAppContext() throws Exception {
// // Context of the app under test.
// Context appContext = InstrumentationRegistry.getTargetContext();
//
// assertEquals("me.weishu.epic", appContext.getPackageName());
// }
//}
================================================
FILE: app/src/main/AndroidManifest.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="me.weishu.epic.samples">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:name=".MainApplication"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/QMUI">
<activity android:name=".MainActivity" android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
================================================
FILE: app/src/main/java/me/weishu/epic/samples/MainActivity.java
================================================
package me.weishu.epic.samples;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.Button;
import android.widget.ExpandableListAdapter;
import android.widget.ExpandableListView;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.List;
import me.weishu.epic.samples.tests.TestCase;
import me.weishu.epic.samples.tests.TestManager;
import me.weishu.epic.samples.tests.TestSuite;
public class MainActivity extends Activity {
private static final String TAG = "MainActivity";
ExpandableListView listView;
List<TestSuite> allSuites;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.i(TAG, "savedInstance:" + savedInstanceState);
setContentView(R.layout.activity_main);
setTitle("Epic Test");
listView = findViewById(R.id.list);
allSuites = TestManager.getInstance().getAllSuites();
ExpandableListAdapter adapter = new MyAdapter();
listView.setAdapter(adapter);
}
private class MyAdapter extends BaseExpandableListAdapter {
@Override
public int getGroupCount() {
return allSuites.size();
}
@Override
public int getChildrenCount(int groupPosition) {
return allSuites.get(groupPosition).getAllCases().size();
}
@Override
public TestSuite getGroup(int groupPosition) {
return allSuites.get(groupPosition);
}
@Override
public TestCase getChild(int groupPosition, int childPosition) {
return allSuites.get(groupPosition).getAllCases().get(childPosition);
}
@Override
public long getGroupId(int groupPosition) {
return 0;
}
@Override
public long getChildId(int groupPosition, int childPosition) {
return 0;
}
@Override
public boolean hasStableIds() {
return false;
}
@Override
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
View parentView = View.inflate(parent.getContext(), R.layout.parent_layout, null);
TextView t = parentView.findViewById(R.id.text);
t.setText(getGroup(groupPosition).getName());
ImageView indicator = parentView.findViewById(R.id.indicator);
if (isExpanded) {
indicator.setImageResource(R.drawable.arrow_down);
} else {
indicator.setImageResource(R.drawable.arrow_up);
}
return parentView;
}
@Override
public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
final TestCase child = getChild(groupPosition, childPosition);
final View childView = View.inflate(parent.getContext(), R.layout.child_layout, null);
final TextView title = childView.findViewById(R.id.label);
title.setText(child.getName());
Button test = childView.findViewById(R.id.test);
test.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
child.test();
}
});
Button validate = childView.findViewById(R.id.validate);
validate.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
boolean validate = child.validate();
final int color = v.getContext().getResources().getColor(validate ?
android.R.color.holo_green_light : android.R.color.holo_red_light);
childView.setBackgroundColor(color);
}
});
return childView;
}
@Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return false;
}
}
}
================================================
FILE: app/src/main/java/me/weishu/epic/samples/MainApplication.java
================================================
package me.weishu.epic.samples;
import android.app.Application;
import android.content.Context;
/**
* Created by weishu on 17/10/31.
*/
public class MainApplication extends Application {
private static Context sContext;
public static Context getAppContext() {
return sContext;
}
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
sContext = base;
}
}
================================================
FILE: app/src/main/java/me/weishu/epic/samples/tests/CallingConventationTest.java
================================================
package me.weishu.epic.samples.tests;
import me.weishu.epic.samples.tests.arguments.ArgumentTarget;
/**
* Created by weishu on 17/11/15.
*/
public class CallingConventationTest {
public static void longParams1() {
// r0 = ArtMethod.this
// r1 = 4
// r2 = 8
// r3 = parital 12
// sp + 16 = partial 12
ArgumentTarget.arg3(4, 8, 12L);
}
public static void longParams2() {
// r0 = ArtMethod
// r1, r2 = 1024L
// r3 = bbcc1122
// sp + 16 = 0xffaa
ArgumentTarget.arg2(1024L, 0xffaabbcc1122L);
}
public static void longParams3() {
ArgumentTarget.arg2(123, 0xffaabbcc1122L);
}
}
================================================
FILE: app/src/main/java/me/weishu/epic/samples/tests/LogMethodHook.java
================================================
package me.weishu.epic.samples.tests;
import android.util.Log;
import java.util.Arrays;
import de.robv.android.xposed.XC_MethodHook;
/**
* Created by weishu on 17/11/13.
*/
public class LogMethodHook extends XC_MethodHook {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
super.beforeHookedMethod(param);
Log.i(getClass().getSimpleName(), "beforeHookedMethod() called with: param = [" + paramToString(param) + "]");
}
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
super.afterHookedMethod(param);
Log.i(getClass().getSimpleName(), "afterHookedMethod() called with: param = [" + paramToString(param) + "]");
}
private static String paramToString(MethodHookParam param) {
StringBuilder sb = new StringBuilder(param.getClass().getSimpleName()).append("{");
sb.append("method = ").append(param.method.getName()).append(", ");
sb.append("this = ").append(param.thisObject).append(", ");
sb.append("args = ").append(Arrays.toString(param.args)).append(",");
sb.append("result = ").append(param.getResult()).append("}");
return sb.toString();
}
}
================================================
FILE: app/src/main/java/me/weishu/epic/samples/tests/TestCase.java
================================================
package me.weishu.epic.samples.tests;
import android.util.Log;
import android.widget.Toast;
import me.weishu.epic.samples.MainApplication;
/**
* Created by weishu on 17/11/13.
*/
public abstract class TestCase {
private static final String TAG = "TestCase";
protected String name;
public TestCase(String name) {
this.name = name;
}
public abstract void test();
public abstract boolean predicate();
public boolean validate() {
boolean validate;
try {
validate = predicate();
} catch (Throwable e) {
validate = false;
Log.e(TAG, "error happened:", e);
}
if (!validate) {
Toast.makeText(MainApplication.getAppContext(), "测试不通过。", Toast.LENGTH_SHORT).show();
}
return validate;
}
public String getName() {
return name;
}
}
================================================
FILE: app/src/main/java/me/weishu/epic/samples/tests/TestManager.java
================================================
package me.weishu.epic.samples.tests;
import android.os.Build;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import me.weishu.epic.samples.tests.arguments.ArgStatic0;
import me.weishu.epic.samples.tests.arguments.ArgStatic4;
import me.weishu.epic.samples.tests.arguments.ArgStatic44;
import me.weishu.epic.samples.tests.arguments.ArgStatic444;
import me.weishu.epic.samples.tests.arguments.ArgStatic4444;
import me.weishu.epic.samples.tests.arguments.ArgStatic4448;
import me.weishu.epic.samples.tests.arguments.ArgStatic448;
import me.weishu.epic.samples.tests.arguments.ArgStatic4484;
import me.weishu.epic.samples.tests.arguments.ArgStatic48;
import me.weishu.epic.samples.tests.arguments.ArgStatic484;
import me.weishu.epic.samples.tests.arguments.ArgStatic4844;
import me.weishu.epic.samples.tests.arguments.ArgStatic488;
import me.weishu.epic.samples.tests.arguments.ArgStatic4888;
import me.weishu.epic.samples.tests.arguments.ArgStatic8;
import me.weishu.epic.samples.tests.arguments.ArgStatic84;
import me.weishu.epic.samples.tests.arguments.ArgStatic844;
import me.weishu.epic.samples.tests.arguments.ArgStatic8444;
import me.weishu.epic.samples.tests.arguments.ArgStatic8448;
import me.weishu.epic.samples.tests.arguments.ArgStatic848;
import me.weishu.epic.samples.tests.arguments.ArgStatic8484;
import me.weishu.epic.samples.tests.arguments.ArgStatic8488;
import me.weishu.epic.samples.tests.arguments.ArgStatic88;
import me.weishu.epic.samples.tests.arguments.ArgStatic884;
import me.weishu.epic.samples.tests.arguments.ArgStatic8844;
import me.weishu.epic.samples.tests.arguments.ArgStatic8848;
import me.weishu.epic.samples.tests.arguments.ArgStatic888;
import me.weishu.epic.samples.tests.arguments.ArgStatic8884;
import me.weishu.epic.samples.tests.arguments.ArgStatic8888;
import me.weishu.epic.samples.tests.custom.Case1;
import me.weishu.epic.samples.tests.custom.Case10_Default_Constructor;
import me.weishu.epic.samples.tests.custom.Case11_SuspendAll;
import me.weishu.epic.samples.tests.custom.Case12_MultiCallback;
import me.weishu.epic.samples.tests.custom.Case13_FastNative;
import me.weishu.epic.samples.tests.custom.Case14_GC;
import me.weishu.epic.samples.tests.custom.Case17_SameMethod;
import me.weishu.epic.samples.tests.custom.Case18_returnConst;
import me.weishu.epic.samples.tests.custom.Case2;
import me.weishu.epic.samples.tests.custom.Case3;
import me.weishu.epic.samples.tests.custom.Case4;
import me.weishu.epic.samples.tests.custom.Case5;
import me.weishu.epic.samples.tests.custom.Case6;
import me.weishu.epic.samples.tests.custom.Case7;
import me.weishu.epic.samples.tests.custom.Case8_Activity_onCreate;
import me.weishu.epic.samples.tests.custom.Case9_ThreadMonitor;
import me.weishu.epic.samples.tests.custom.CaseManager;
import me.weishu.epic.samples.tests.invoketype.InvokeConstructor;
import me.weishu.epic.samples.tests.returntype.BooleanType;
import me.weishu.epic.samples.tests.returntype.ByteType;
import me.weishu.epic.samples.tests.returntype.CharType;
import me.weishu.epic.samples.tests.returntype.CustomType;
import me.weishu.epic.samples.tests.returntype.DoubleType;
import me.weishu.epic.samples.tests.returntype.FloatType;
import me.weishu.epic.samples.tests.returntype.IntType;
import me.weishu.epic.samples.tests.returntype.LongType;
import me.weishu.epic.samples.tests.returntype.ShortType;
import me.weishu.epic.samples.tests.returntype.StringArrayType;
import me.weishu.epic.samples.tests.returntype.StringType;
import me.weishu.epic.samples.tests.returntype.VoidType;
/**
* Created by weishu on 17/11/13.
*/
public class TestManager {
private static TestManager sManager = new TestManager();
private List<TestSuite> suites = new ArrayList<>();
private TestManager() {
initAllSuites();
}
public static TestManager getInstance() {
return sManager;
}
public void addSuite(TestSuite suite) {
suites.add(suite);
}
public List<TestSuite> getAllSuites() {
return suites;
}
private void initAllSuites() {
TestSuite returnType = new TestSuite("返回值测试");
returnType.addCase(new VoidType());
returnType.addCase(new ByteType());
returnType.addCase(new ShortType());
returnType.addCase(new CharType());
returnType.addCase(new IntType());
returnType.addCase(new FloatType());
returnType.addCase(new LongType());
returnType.addCase(new DoubleType());
returnType.addCase(new BooleanType());
returnType.addCase(new StringType());
returnType.addCase(new StringArrayType());
returnType.addCase(new CustomType());
addSuite(returnType);
TestSuite arguments = new TestSuite("参数测试");
arguments.addCase(new ArgStatic0());
arguments.addCase(new ArgStatic4());
arguments.addCase(new ArgStatic8());
arguments.addCase(new ArgStatic44());
arguments.addCase(new ArgStatic48());
arguments.addCase(new ArgStatic84());
arguments.addCase(new ArgStatic88());
arguments.addCase(new ArgStatic444());
arguments.addCase(new ArgStatic448());
arguments.addCase(new ArgStatic484());
arguments.addCase(new ArgStatic844());
arguments.addCase(new ArgStatic488());
arguments.addCase(new ArgStatic848());
arguments.addCase(new ArgStatic884());
arguments.addCase(new ArgStatic888());
arguments.addCase(new ArgStatic4444());
arguments.addCase(new ArgStatic4448());
arguments.addCase(new ArgStatic4484());
arguments.addCase(new ArgStatic4844());
arguments.addCase(new ArgStatic8444());
arguments.addCase(new ArgStatic8844());
arguments.addCase(new ArgStatic8484());
arguments.addCase(new ArgStatic8448());
arguments.addCase(new ArgStatic8884());
arguments.addCase(new ArgStatic8848());
arguments.addCase(new ArgStatic8488());
arguments.addCase(new ArgStatic4888());
arguments.addCase(new ArgStatic8888());
addSuite(arguments);
TestSuite invokeType = new TestSuite("调用类型");
invokeType.addCase(new InvokeConstructor());
addSuite(invokeType);
TestSuite custom = new TestSuite("自定义");
CaseManager.getInstance().getCase(Case1.class);
CaseManager.getInstance().getCase(Case2.class);
CaseManager.getInstance().getCase(Case3.class);
CaseManager.getInstance().getCase(Case4.class);
CaseManager.getInstance().getCase(Case4.class);
CaseManager.getInstance().getCase(Case5.class);
CaseManager.getInstance().getCase(Case6.class);
CaseManager.getInstance().getCase(Case7.class);
CaseManager.getInstance().getCase(Case8_Activity_onCreate.class);
CaseManager.getInstance().getCase(Case9_ThreadMonitor.class);
CaseManager.getInstance().getCase(Case10_Default_Constructor.class);
CaseManager.getInstance().getCase(Case12_MultiCallback.class);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
CaseManager.getInstance().getCase(Case11_SuspendAll.class);
CaseManager.getInstance().getCase(Case14_GC.class);
// CaseManager.getInstance().getCase(Case15_StopJit.class);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
CaseManager.getInstance().getCase(Case13_FastNative.class);
}
// CaseManager.getInstance().getCase(Case16_SameEntry.class);
CaseManager.getInstance().getCase(Case17_SameMethod.class);
CaseManager.getInstance().getCase(Case18_returnConst.class);
final Set<Class<?>> cases = CaseManager.getInstance().getCases();
for (final Class<?> aCase : cases) {
custom.addCase(new TestCase(aCase.getSimpleName()) {
@Override
public void test() {
CaseManager.getInstance().getCase(aCase).hook();
}
@Override
public boolean predicate() {
return CaseManager.getInstance().getCase(aCase).validate();
}
});
}
addSuite(custom);
}
}
================================================
FILE: app/src/main/java/me/weishu/epic/samples/tests/TestSuite.java
================================================
package me.weishu.epic.samples.tests;
import java.util.ArrayList;
import java.util.List;
/**
* Created by weishu on 17/11/13.
*/
public class TestSuite {
private String name;
private List<TestCase> cases = new ArrayList<>();
public TestSuite(String name) {
this.name = name;
}
public void addCase(TestCase caze) {
cases.add(caze);
}
public String getName() {
return name;
}
public List<TestCase> getAllCases() {
return cases;
}
}
================================================
FILE: app/src/main/java/me/weishu/epic/samples/tests/arguments/AbsArgStaticCase.java
================================================
package me.weishu.epic.samples.tests.arguments;
import android.util.Log;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Random;
import de.robv.android.xposed.DexposedBridge;
import de.robv.android.xposed.XposedHelpers;
import me.weishu.epic.samples.tests.LogMethodHook;
import me.weishu.epic.samples.tests.TestCase;
/**
* @author weishu
* @date 17/11/14.
*/
public abstract class AbsArgStaticCase extends TestCase {
private final String TAG = getClass().getSimpleName();
final long[] args;
private Random r = new Random();
public AbsArgStaticCase() {
super(null);
args = new long[8];
for (int i = 0; i < args.length; i++) {
args[i] = 0L;
}
name = getClass().getSimpleName();
}
@Override
public void test() {
DexposedBridge.hookMethod(getTargetMethod(), new LogMethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
super.beforeHookedMethod(param);
int length = param.args.length;
if (length > 0) {
for (int i = 0; i < length; i++) {
long tmp = ((Number) param.args[i]).longValue();
args[i] = tmp;
}
}
}
});
}
@Override
public boolean predicate() {
long[] arguments = getArguments();
Log.i(TAG, "call arguments: " + Arrays.toString(toHex(arguments)));
makeCall(arguments);
boolean ret = true;
int length = getArgumentNumber();
for (int i = 0; i < length; i++) {
if (arguments[i] != args[i]) {
ret = false;
Log.i(TAG, "hooked arguments: " + Arrays.toString(toHex(args)));
}
}
return ret;
}
private long[] getArguments() {
final int argumentNumber = getArgumentNumber();
long[] arguments = new long[argumentNumber];
for (int i = 0; i < arguments.length; i++) {
arguments[i] = nextLong();
}
return arguments;
}
protected Method getTargetMethod() {
final int argumentNumber = getArgumentNumber();
String methodName = "arg" + argumentNumber;
Method method = XposedHelpers.findMethodExact(ArgumentTarget.class, methodName, getParamsSignature());
Log.i(TAG, "find target Method:" + method);
return method;
}
protected int getArgumentNumber() {
return getParamsSignature().length;
}
protected void makeCall(long... args) {
Log.i(TAG, getName() + " make call with arguments:" + Arrays.toString(args));
}
private long nextLong() {
int ret = r.nextInt();
return ret;
}
private Class<?>[] getParamsSignature() {
String className = getClass().getSimpleName();
String signature = className.substring("ArgStatic".length());
final int length = signature.length();
Class<?>[] clazz = new Class<?>[length];
for (int i = 0; i < length; i++) {
final char c = signature.charAt(i);
if (c == '4') {
clazz[i] = int.class;
} else if (c == '8') {
clazz[i] = long.class;
} else {
throw new RuntimeException("Unknown signature!!");
}
}
return clazz;
}
private String[] toHex(long[] value) {
String[] ret = new String[value.length];
for (int i = 0; i < value.length; i++) {
ret[i] = Long.toHexString(value[i]);
}
return ret;
}
}
================================================
FILE: app/src/main/java/me/weishu/epic/samples/tests/arguments/ArgStatic0.java
================================================
package me.weishu.epic.samples.tests.arguments;
import de.robv.android.xposed.DexposedBridge;
import de.robv.android.xposed.XC_MethodHook;
import me.weishu.epic.samples.tests.LogMethodHook;
import me.weishu.epic.samples.tests.TestCase;
/**
* @author weishu
* @date 17/11/14.
*/
public class ArgStatic0 extends TestCase {
boolean beforeCalled = false;
boolean afterCalled = false;
public ArgStatic0() {
super("ArgStatic0");
}
@Override
public void test() {
DexposedBridge.findAndHookMethod(ArgumentTarget.class, "arg0", new LogMethodHook() {
@Override
protected void beforeHookedMethod(XC_MethodHook.MethodHookParam param) throws Throwable {
super.beforeHookedMethod(param);
beforeCalled = true;
}
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
super.afterHookedMethod(param);
afterCalled = true;
}
});
}
@Override
public boolean predicate() {
ArgumentTarget.arg0();
return beforeCalled && afterCalled;
}
}
================================================
FILE: app/src/main/java/me/weishu/epic/samples/tests/arguments/ArgStatic4.java
================================================
package me.weishu.epic.samples.tests.arguments;
/**
* @author weishu
* @date 17/11/14.
*/
public class ArgStatic4 extends AbsArgStaticCase {
@Override
protected void makeCall(long... args) {
ArgumentTarget.arg1((int)args[0]);
}
}
================================================
FILE: app/src/main/java/me/weishu/epic/samples/tests/arguments/ArgStatic44.java
================================================
package me.weishu.epic.samples.tests.arguments;
/**
* @author weishu
* @date 17/11/14.
*/
public class ArgStatic44 extends AbsArgStaticCase {
@Override
protected void makeCall(long... args) {
ArgumentTarget.arg2((int) args[0], (int) args[1]);
}
}
================================================
FILE: app/src/main/java/me/weishu/epic/samples/tests/arguments/ArgStatic444.java
================================================
package me.weishu.epic.samples.tests.arguments;
import android.util.Log;
import java.util.Arrays;
/**
* Created by weishu on 17/11/14.
*/
public class ArgStatic444 extends AbsArgStaticCase {
@Override
protected void makeCall(long... args) {
Log.i("mylog", "make call args:" + Arrays.toString(args));
ArgumentTarget.arg3((int) args[0], (int) args[1], (int) args[2]);
}
}
================================================
FILE: app/src/main/java/me/weishu/epic/samples/tests/arguments/ArgStatic4444.java
================================================
package me.weishu.epic.samples.tests.arguments;
/**
* Created by weishu on 17/11/14.
*/
public class ArgStatic4444 extends AbsArgStaticCase {
@Override
protected void makeCall(long... args) {
ArgumentTarget.arg4((int)args[0], (int)args[1], (int)args[2], (int)args[3]);
}
}
================================================
FILE: app/src/main/java/me/weishu/epic/samples/tests/arguments/ArgStatic4448.java
================================================
package me.weishu.epic.samples.tests.arguments;
/**
* Created by weishu on 17/11/14.
*/
public class ArgStatic4448 extends AbsArgStaticCase {
@Override
protected void makeCall(long... args) {
ArgumentTarget.arg4((int) args[0], (int)args[1], (int)args[2], args[3]);
}
}
================================================
FILE: app/src/main/java/me/weishu/epic/samples/tests/arguments/ArgStatic448.java
================================================
package me.weishu.epic.samples.tests.arguments;
/**
* Created by weishu on 17/11/14.
*/
public class ArgStatic448 extends AbsArgStaticCase {
@Override
protected void makeCall(long... args) {
ArgumentTarget.arg3((int) args[0], (int) args[1], args[2]);
}
}
================================================
FILE: app/src/main/java/me/weishu/epic/samples/tests/arguments/ArgStatic4484.java
================================================
package me.weishu.epic.samples.tests.arguments;
/**
* Created by weishu on 17/11/14.
*/
public class ArgStatic4484 extends AbsArgStaticCase {
@Override
protected void makeCall(long... args) {
ArgumentTarget.arg4((int)args[0], (int)args[1], args[2], (int) args[3]);
}
}
================================================
FILE: app/src/main/java/me/weishu/epic/samples/tests/arguments/ArgStatic4488.java
================================================
package me.weishu.epic.samples.tests.arguments;
/**
* Created by weishu on 17/11/14.
*/
public class ArgStatic4488 extends AbsArgStaticCase {
@Override
protected void makeCall(long... args) {
ArgumentTarget.arg4((int)args[0], (int)args[1], args[2], args[3]);
}
}
================================================
FILE: app/src/main/java/me/weishu/epic/samples/tests/arguments/ArgStatic48.java
================================================
package me.weishu.epic.samples.tests.arguments;
/**
* @author weishu
* @date 17/11/14.
*/
public class ArgStatic48 extends AbsArgStaticCase {
@Override
protected void makeCall(long... args) {
ArgumentTarget.arg2((int) args[0], args[1]);
}
}
================================================
FILE: app/src/main/java/me/weishu/epic/samples/tests/arguments/ArgStatic484.java
================================================
package me.weishu.epic.samples.tests.arguments;
/**
* Created by weishu on 17/11/14.
*/
public class ArgStatic484 extends AbsArgStaticCase {
@Override
protected void makeCall(long... args) {
ArgumentTarget.arg3((int) args[0], args[1], (int) args[2]);
}
}
================================================
FILE: app/src/main/java/me/weishu/epic/samples/tests/arguments/ArgStatic4844.java
================================================
package me.weishu.epic.samples.tests.arguments;
/**
* Created by weishu on 17/11/14.
*/
public class ArgStatic4844 extends AbsArgStaticCase {
@Override
protected void makeCall(long... args) {
ArgumentTarget.arg4((int) args[0], args[1], (int)args[2], (int)args[3]);
}
}
================================================
FILE: app/src/main/java/me/weishu/epic/samples/tests/arguments/ArgStatic4848.java
================================================
package me.weishu.epic.samples.tests.arguments;
/**
* Created by weishu on 17/11/14.
*/
public class ArgStatic4848 extends AbsArgStaticCase {
@Override
protected void makeCall(long... args) {
ArgumentTarget.arg4((int)args[0], args[1], (int)args[2], args[3]);
}
}
================================================
FILE: app/src/main/java/me/weishu/epic/samples/tests/arguments/ArgStatic488.java
================================================
package me.weishu.epic.samples.tests.arguments;
/**
* Created by weishu on 17/11/14.
*/
public class ArgStatic488 extends AbsArgStaticCase {
@Override
protected void makeCall(long... args) {
ArgumentTarget.arg3((int) args[0], args[1], args[2]);
}
}
================================================
FILE: app/src/main/java/me/weishu/epic/samples/tests/arguments/ArgStatic4884.java
================================================
package me.weishu.epic.samples.tests.arguments;
/**
* Created by weishu on 17/11/14.
*/
public class ArgStatic4884 extends AbsArgStaticCase {
@Override
protected void makeCall(long... args) {
ArgumentTarget.arg4((int)args[0], args[1], args[2], (int)args[3]);
}
}
================================================
FILE: app/src/main/java/me/weishu/epic/samples/tests/arguments/ArgStatic4888.java
================================================
package me.weishu.epic.samples.tests.arguments;
/**
* Created by weishu on 17/11/14.
*/
public class ArgStatic4888 extends AbsArgStaticCase {
@Override
protected void makeCall(long... args) {
ArgumentTarget.arg4((int)args[0], args[1], args[2], args[3]);
}
}
================================================
FILE: app/src/main/java/me/weishu/epic/samples/tests/arguments/ArgStatic8.java
================================================
package me.weishu.epic.samples.tests.arguments;
/**
* @author weishu
* @date 17/11/14.
*/
public class ArgStatic8 extends AbsArgStaticCase {
@Override
protected void makeCall(long... args) {
ArgumentTarget.arg1(args[0]);
}
}
================================================
FILE: app/src/main/java/me/weishu/epic/samples/tests/arguments/ArgStatic84.java
================================================
package me.weishu.epic.samples.tests.arguments;
/**
* @author weishu
* @date 17/11/14.
*/
public class ArgStatic84 extends AbsArgStaticCase {
@Override
protected void makeCall(long... args) {
ArgumentTarget.arg2(args[0], (int)args[1]);
}
}
================================================
FILE: app/src/main/java/me/weishu/epic/samples/tests/arguments/ArgStatic844.java
================================================
package me.weishu.epic.samples.tests.arguments;
/**
* Created by weishu on 17/11/14.
*/
public class ArgStatic844 extends AbsArgStaticCase {
@Override
protected void makeCall(long... args) {
ArgumentTarget.arg3(args[0], (int) args[1], (int) args[2]);
}
}
================================================
FILE: app/src/main/java/me/weishu/epic/samples/tests/arguments/ArgStatic8444.java
================================================
package me.weishu.epic.samples.tests.arguments;
/**
* Created by weishu on 17/11/14.
*/
public class ArgStatic8444 extends AbsArgStaticCase {
@Override
protected void makeCall(long... args) {
ArgumentTarget.arg4(args[0], (int)args[1], (int)args[2], (int)args[3]);
}
}
================================================
FILE: app/src/main/java/me/weishu/epic/samples/tests/arguments/ArgStatic8448.java
================================================
package me.weishu.epic.samples.tests.arguments;
/**
* Created by weishu on 17/11/14.
*/
public class ArgStatic8448 extends AbsArgStaticCase {
@Override
protected void makeCall(long... args) {
ArgumentTarget.arg4(args[0], (int)args[1], (int)args[2], args[3]);
}
}
================================================
FILE: app/src/main/java/me/weishu/epic/samples/tests/arguments/ArgStatic848.java
================================================
package me.weishu.epic.samples.tests.arguments;
/**
* Created by weishu on 17/11/14.
*/
public class ArgStatic848 extends AbsArgStaticCase {
@Override
protected void makeCall(long... args) {
ArgumentTarget.arg3(args[0], (int) args[1], args[2]);
}
}
================================================
FILE: app/src/main/java/me/weishu/epic/samples/tests/arguments/ArgStatic8484.java
================================================
package me.weishu.epic.samples.tests.arguments;
/**
* Created by weishu on 17/11/14.
*/
public class ArgStatic8484 extends AbsArgStaticCase {
@Override
protected void makeCall(long... args) {
ArgumentTarget.arg4(args[0], (int)args[1], args[2], (int)args[3]);
}
}
================================================
FILE: app/src/main/java/me/weishu/epic/samples/tests/arguments/ArgStatic8488.java
================================================
package me.weishu.epic.samples.tests.arguments;
/**
* Created by weishu on 17/11/14.
*/
public class ArgStatic8488 extends AbsArgStaticCase {
@Override
protected void makeCall(long... args) {
ArgumentTarget.arg4(args[0], (int)args[1], args[2], args[3]);
}
}
================================================
FILE: app/src/main/java/me/weishu/epic/samples/tests/arguments/ArgStatic88.java
================================================
package me.weishu.epic.samples.tests.arguments;
/**
* @author weishu
* @date 17/11/14.
*/
public class ArgStatic88 extends AbsArgStaticCase {
@Override
protected void makeCall(long... args) {
super.makeCall(args);
ArgumentTarget.arg2(args[0], args[1]);
}
}
================================================
FILE: app/src/main/java/me/weishu/epic/samples/tests/arguments/ArgStatic884.java
================================================
package me.weishu.epic.samples.tests.arguments;
/**
* Created by weishu on 17/11/14.
*/
public class ArgStatic884 extends AbsArgStaticCase {
@Override
protected void makeCall(long... args) {
ArgumentTarget.arg3(args[0], args[1], (int) args[2]);
}
}
================================================
FILE: app/src/main/java/me/weishu/epic/samples/tests/arguments/ArgStatic8844.java
================================================
package me.weishu.epic.samples.tests.arguments;
/**
* Created by weishu on 17/11/14.
*/
public class ArgStatic8844 extends AbsArgStaticCase {
@Override
protected void makeCall(long... args) {
ArgumentTarget.arg4(args[0], args[1], (int)args[2], (int)args[3]);
}
}
================================================
FILE: app/src/main/java/me/weishu/epic/samples/tests/arguments/ArgStatic8848.java
================================================
package me.weishu.epic.samples.tests.arguments;
/**
* Created by weishu on 17/11/14.
*/
public class ArgStatic8848 extends AbsArgStaticCase {
@Override
protected void makeCall(long... args) {
ArgumentTarget.arg4(args[0], args[1], (int)args[2], args[3]);
}
}
================================================
FILE: app/src/main/java/me/weishu/epic/samples/tests/arguments/ArgStatic888.java
================================================
package me.weishu.epic.samples.tests.arguments;
/**
* Created by weishu on 17/11/14.
*/
public class ArgStatic888 extends AbsArgStaticCase {
@Override
protected void makeCall(long... args) {
ArgumentTarget.arg3(args[0], args[1], args[2]);
}
}
================================================
FILE: app/src/main/java/me/weishu/epic/samples/tests/arguments/ArgStatic8884.java
================================================
package me.weishu.epic.samples.tests.arguments;
/**
* Created by weishu on 17/11/14.
*/
public class ArgStatic8884 extends AbsArgStaticCase {
@Override
protected void makeCall(long... args) {
ArgumentTarget.arg4(args[0], args[1], args[2], (int)args[3]);
}
}
================================================
FILE: app/src/main/java/me/weishu/epic/samples/tests/arguments/ArgStatic8888.java
================================================
package me.weishu.epic.samples.tests.arguments;
/**
* Created by weishu on 17/11/14.
*/
public class ArgStatic8888 extends AbsArgStaticCase {
@Override
protected void makeCall(long... args) {
ArgumentTarget.arg4(args[0], args[1], args[2], args[3]);
}
}
================================================
FILE: app/src/main/java/me/weishu/epic/samples/tests/arguments/ArgumentTarget.java
================================================
package me.weishu.epic.samples.tests.arguments;
import android.util.Log;
/**
* @author weishu
* @date 17/11/13.
*/
public class ArgumentTarget {
private static final String TAG = "ArgumentTarget";
//region ---------------static---------------
public static void arg0() {
Log.i(TAG, "arg0() called");
}
public static void arg1(int v1) {
Log.i(TAG, "arg1() called with: v1 = [" + v1 + "]");
}
public static void arg1(long v1) {
Log.i(TAG, "arg1() called with: v1 = [" + v1 + "]");
}
public static void arg2(int v1, int v2) {
Log.i(TAG, "arg2() called with: v1 = [" + v1 + "], v2 = [" + v2 + "]");
}
public static void arg2(int v1, long v2) {
Log.i(TAG, "arg2() called with: v1 = [" + v1 + "], v2 = [" + v2 + "]");
}
public static void arg2(long v1, int v2) {
Log.i(TAG, "arg2() called with: v1 = [" + v1 + "], v2 = [" + v2 + "]");
}
public static void arg2(long v1, long v2) {
Log.i(TAG, "arg2() called with: v1 = [" + v1 + "], v2 = [" + v2 + "]");
}
public static void arg3(int v1, int v2, int v3) {
Log.i(TAG, "arg3() called with: v1 = [" + v1 + "], v2 = [" + v2 + "], v3 = [" + v3 + "]");
}
public static void arg3(long v1, int v2, int v3) {
Log.i(TAG, "arg3() called with: v1 = [" + v1 + "], v2 = [" + v2 + "], v3 = [" + v3 + "]");
}
public static void arg3(int v1, long v2, int v3) {
Log.i(TAG, "arg3() called with: v1 = [" + v1 + "], v2 = [" + v2 + "], v3 = [" + v3 + "]");
}
public static void arg3(int v1, int v2, long v3) {
Log.i(TAG, "arg3() called with: v1 = [" + v1 + "], v2 = [" + v2 + "], v3 = [" + v3 + "]");
}
public static void arg3(long v1, long v2, int v3) {
Log.i(TAG, "arg3() called with: v1 = [" + v1 + "], v2 = [" + v2 + "], v3 = [" + v3 + "]");
}
public static void arg3(long v1, int v2, long v3) {
Log.i(TAG, "arg3() called with: v1 = [" + v1 + "], v2 = [" + v2 + "], v3 = [" + v3 + "]");
}
public static void arg3(int v1, long v2, long v3) {
Log.i(TAG, "arg3() called with: v1 = [" + v1 + "], v2 = [" + v2 + "], v3 = [" + v3 + "]");
}
public static void arg3(long v1, long v2, long v3) {
Log.i(TAG, "arg3() called with: v1 = [" + v1 + "], v2 = [" + v2 + "], v3 = [" + v3 + "]");
}
public static void arg4(int v1, int v2, int v3, int v4) {
Log.i(TAG, "arg4() called with: v1 = [" + v1 + "], v2 = [" + v2 + "], v3 = [" + v3 + "], v4 = [" + v4 + "]");
}
public static void arg4(long v1, int v2, int v3, int v4) {
Log.i(TAG, "arg4() called with: v1 = [" + v1 + "], v2 = [" + v2 + "], v3 = [" + v3 + "], v4 = [" + v4 + "]");
}
public static void arg4(int v1, long v2, int v3, int v4) {
Log.i(TAG, "arg4() called with: v1 = [" + v1 + "], v2 = [" + v2 + "], v3 = [" + v3 + "], v4 = [" + v4 + "]");
}
public static void arg4(int v1, int v2, long v3, int v4) {
Log.i(TAG, "arg4() called with: v1 = [" + v1 + "], v2 = [" + v2 + "], v3 = [" + v3 + "], v4 = [" + v4 + "]");
}
public static void arg4(int v1, int v2, int v3, long v4) {
Log.i(TAG, "arg4() called with: v1 = [" + v1 + "], v2 = [" + v2 + "], v3 = [" + v3 + "], v4 = [" + v4 + "]");
}
public static void arg4(long v1, long v2, int v3, int v4) {
Log.i(TAG, "arg4() called with: v1 = [" + v1 + "], v2 = [" + v2 + "], v3 = [" + v3 + "], v4 = [" + v4 + "]");
}
public static void arg4(long v1, int v2, long v3, int v4) {
Log.i(TAG, "arg4() called with: v1 = [" + v1 + "], v2 = [" + v2 + "], v3 = [" + v3 + "], v4 = [" + v4 + "]");
}
public static void arg4(long v1, int v2, int v3, long v4) {
Log.i(TAG, "arg4() called with: v1 = [" + v1 + "], v2 = [" + v2 + "], v3 = [" + v3 + "], v4 = [" + v4 + "]");
}
public static void arg4(int v1, long v2, long v3, int v4) {
Log.i(TAG, "arg4() called with: v1 = [" + v1 + "], v2 = [" + v2 + "], v3 = [" + v3 + "], v4 = [" + v4 + "]");
}
public static void arg4(int v1, long v2, int v3, long v4) {
Log.i(TAG, "arg4() called with: v1 = [" + v1 + "], v2 = [" + v2 + "], v3 = [" + v3 + "], v4 = [" + v4 + "]");
}
public static void arg4(int v1, int v2, long v3, long v4) {
Log.i(TAG, "arg4() called with: v1 = [" + v1 + "], v2 = [" + v2 + "], v3 = [" + v3 + "], v4 = [" + v4 + "]");
}
public static void arg4(int v1, long v2, long v3, long v4) {
Log.i(TAG, "arg4() called with: v1 = [" + v1 + "], v2 = [" + v2 + "], v3 = [" + v3 + "], v4 = [" + v4 + "]");
}
public static void arg4(long v1, int v2, long v3, long v4) {
Log.i(TAG, "arg4() called with: v1 = [" + v1 + "], v2 = [" + v2 + "], v3 = [" + v3 + "], v4 = [" + v4 + "]");
}
public static void arg4(long v1, long v2, int v3, long v4) {
Log.i(TAG, "arg4() called with: v1 = [" + v1 + "], v2 = [" + v2 + "], v3 = [" + v3 + "], v4 = [" + v4 + "]");
}
public static void arg4(long v1, long v2, long v3, int v4) {
Log.i(TAG, "arg4() called with: v1 = [" + v1 + "], v2 = [" + v2 + "], v3 = [" + v3 + "], v4 = [" + v4 + "]");
}
public static void arg4(long v1, long v2, long v3, long v4) {
Log.i(TAG, "arg4() called with: v1 = [" + v1 + "], v2 = [" + v2 + "], v3 = [" + v3 + "], v4 = [" + v4 + "]");
}
public static void arg5(int v1, int v2, int v3, int v4, int v5) {
Log.i(TAG, "arg5() called with: v1 = [" + v1 + "], v2 = [" + v2 + "], v3 = [" + v3 + "], v4 = [" + v4 + "], v5 = [" + v5 + "]");
}
public static void arg5(long v1, long v2, long v3, long v4, long v5) {
Log.i(TAG, "arg5() called with: v1 = [" + v1 + "], v2 = [" + v2 + "], v3 = [" + v3 + "], v4 = [" + v4 + "], v5 = [" + v5 + "]");
}
public static void arg6(int v1, int v2, int v3, int v4, int v5, int v6) {
Log.i(TAG, "arg6() called with: v1 = [" + v1 + "], v2 = [" + v2 + "], v3 = [" + v3 + "], v4 = [" + v4 + "], v5 = [" + v5 + "], v6 = [" + v6 + "]");
}
public static void arg6(long v1, long v2, long v3, long v4, long v5, long v6) {
Log.i(TAG, "arg6() called with: v1 = [" + v1 + "], v2 = [" + v2 + "], v3 = [" + v3 + "], v4 = [" + v4 + "], v5 = [" + v5 + "], v6 = [" + v6 + "]");
}
public static void arg7(int v1, int v2, int v3, int v4, int v5, int v6, int v7) {
Log.i(TAG, "arg7() called with: v1 = [" + v1 + "], v2 = [" + v2 + "], v3 = [" + v3 + "], v4 = [" + v4 + "], v5 = [" + v5 + "], v6 = [" + v6 + "], v7 = [" + v7 + "]");
}
public static void arg7(long v1, long v2, long v3, long v4, long v5, long v6, long v7) {
Log.i(TAG, "arg7() called with: v1 = [" + v1 + "], v2 = [" + v2 + "], v3 = [" + v3 + "], v4 = [" + v4 + "], v5 = [" + v5 + "], v6 = [" + v6 + "], v7 = [" + v7 + "]");
}
//endregion
//region ---------------non static---------------
public void iarg0() {
Log.i(TAG, "arg0() called");
}
public void iarg1(int v1) {
Log.i(TAG, "arg1() called with: v1 = [" + v1 + "]");
}
public void iarg1(long v1) {
Log.i(TAG, "arg1() called with: v1 = [" + v1 + "]");
}
public void iarg2(int v1, int v2) {
Log.i(TAG, "arg2() called with: v1 = [" + v1 + "], v2 = [" + v2 + "]");
}
public void iarg2(int v1, long v2) {
Log.i(TAG, "arg2() called with: v1 = [" + v1 + "], v2 = [" + v2 + "]");
}
public void iarg2(long v1, long v2) {
Log.i(TAG, "arg2() called with: v1 = [" + v1 + "], v2 = [" + v2 + "]");
}
public void iarg3(int v1, int v2, int v3) {
Log.i(TAG, "arg3() called with: v1 = [" + v1 + "], v2 = [" + v2 + "], v3 = [" + v3 + "]");
}
public void iarg3(long v1, int v2, int v3) {
Log.i(TAG, "arg3() called with: v1 = [" + v1 + "], v2 = [" + v2 + "], v3 = [" + v3 + "]");
}
public void iarg3(int v1, long v2, int v3) {
Log.i(TAG, "arg3() called with: v1 = [" + v1 + "], v2 = [" + v2 + "], v3 = [" + v3 + "]");
}
public void iarg3(int v1, int v2, long v3) {
Log.i(TAG, "arg3() called with: v1 = [" + v1 + "], v2 = [" + v2 + "], v3 = [" + v3 + "]");
}
public void iarg3(long v1, long v2, int v3) {
Log.i(TAG, "arg3() called with: v1 = [" + v1 + "], v2 = [" + v2 + "], v3 = [" + v3 + "]");
}
public void iarg3(long v1, int v2, long v3) {
Log.i(TAG, "arg3() called with: v1 = [" + v1 + "], v2 = [" + v2 + "], v3 = [" + v3 + "]");
}
public void iarg3(int v1, long v2, long v3) {
Log.i(TAG, "arg3() called with: v1 = [" + v1 + "], v2 = [" + v2 + "], v3 = [" + v3 + "]");
}
public void iarg3(long v1, long v2, long v3) {
Log.i(TAG, "arg3() called with: v1 = [" + v1 + "], v2 = [" + v2 + "], v3 = [" + v3 + "]");
}
//endregion
}
================================================
FILE: app/src/main/java/me/weishu/epic/samples/tests/custom/Case.java
================================================
package me.weishu.epic.samples.tests.custom;
/**
* Created by weishu on 17/11/6.
*/
public interface Case {
void hook();
boolean validate(Object... args);
}
================================================
FILE: app/src/main/java/me/weishu/epic/samples/tests/custom/Case1.java
================================================
package me.weishu.epic.samples.tests.custom;
import android.os.SystemClock;
import android.util.Log;
import java.lang.reflect.Field;
import de.robv.android.xposed.DexposedBridge;
import de.robv.android.xposed.XC_MethodHook;
/**
* Created by weishu on 17/11/6.
*/
public class Case1 implements Case {
static Field sThread$target;
static {
try {
// Thread#target
sThread$target = Thread.class.getDeclaredField("target");
sThread$target.setAccessible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
private static final String TAG = "Case1";
@Override
public void hook() {
DexposedBridge.findAndHookMethod(Thread.class, "run", new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
super.afterHookedMethod(param);
Log.i(TAG, "afterHookedMethod: " + param.thisObject);
Thread thread = (Thread) param.thisObject;
Runnable target = (Runnable) sThread$target.get(thread);
// start|threadName|priority|class|startTime|stacktrace
Log.i(TAG, "runnable target:" + target);
}
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
super.beforeHookedMethod(param);
Log.i(TAG, "beforeHookedMethod: " + param.thisObject);
}
});
}
@Override
public boolean validate(Object...args) {
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
Log.i(TAG, "before sleep");
SystemClock.sleep(3000);
Log.i(TAG, "after sleep");
}
});
t1.start();
class MyThread extends Thread {
@Override
public void run() {
super.run();
Log.i(TAG, "before sleep");
SystemClock.sleep(3000);
Log.i(TAG, "after sleep");
}
}
Thread t2 = new MyThread();
t2.start();
return true;
}
}
================================================
FILE: app/src/main/java/me/weishu/epic/samples/tests/custom/Case10_Default_Constructor.java
================================================
package me.weishu.epic.samples.tests.custom;
import android.util.Log;
import java.lang.reflect.Constructor;
import de.robv.android.xposed.DexposedBridge;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XposedHelpers;
/**
* Created by weishu on 17/11/13.
*/
public class Case10_Default_Constructor implements Case {
private static final String TAG = "Case10_Default_Constructor";
@Override
public void hook() {
Constructor<?> constructor = XposedHelpers.findConstructorExact(Target.class);
DexposedBridge.hookMethod(constructor, new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
super.beforeHookedMethod(param);
Log.i(TAG, "Target constructor called");
}
});
}
@Override
public boolean validate(Object... args) {
new Target();
return true;
}
}
================================================
FILE: app/src/main/java/me/weishu/epic/samples/tests/custom/Case11_SuspendAll.java
================================================
package me.weishu.epic.samples.tests.custom;
import android.os.Build;
import android.os.SystemClock;
import android.util.Log;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import me.weishu.epic.art.EpicNative;
/**
* Created by weishu on 17/11/18.
*/
public class Case11_SuspendAll implements Case {
private static final String TAG = "Case11_SuspendAll";
@Override
public void hook() {
Executor executor = Executors.newCachedThreadPool();
for (int i = 0; i < 5; i++) {
executor.execute(new Runnable() {
@Override
public void run() {
int j = 0;
while (true) {
Log.i(TAG, "I am:" + Thread.currentThread().getName() + ", count:" + (j++));
SystemClock.sleep(1000);
if (j > 3) {
break;
}
}
}
});
}
}
@Override
public boolean validate(Object... args) {
if (Build.VERSION.SDK_INT < 24) {
Log.i(TAG, "resume/suspend only support Android N+ now.");
return false;
}
long cookie = EpicNative.suspendAll();
for (Thread thread : Thread.getAllStackTraces().keySet()) {
Log.i(TAG, thread.getName() + " status:" + thread.getState());
}
EpicNative.resumeAll(cookie);
return true;
}
}
================================================
FILE: app/src/main/java/me/weishu/epic/samples/tests/custom/Case12_MultiCallback.java
================================================
package me.weishu.epic.samples.tests.custom;
import android.util.Log;
import de.robv.android.xposed.DexposedBridge;
import de.robv.android.xposed.XC_MethodHook;
/**
* Created by weishu on 17/11/21.
*/
public class Case12_MultiCallback implements Case {
private static final String TAG = "Case12_MultiCallback";
int beforeCount = 0;
int afterCount = 0;
XC_MethodHook callback1 = new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
super.beforeHookedMethod(param);
Log.i(TAG, "beforeHookMethod 1");
beforeCount++;
}
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
super.afterHookedMethod(param);
Log.i(TAG, "afterHookMethod 1");
afterCount++;
}
};
XC_MethodHook callback2 = new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
super.beforeHookedMethod(param);
Log.i(TAG, "beforeHookMethod 2 lalala ");
beforeCount++;
}
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
super.afterHookedMethod(param);
Log.i(TAG, "afterHookMethod 2 lalala");
afterCount++;
}
};
XC_MethodHook callback3 = new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
super.beforeHookedMethod(param);
Log.i(TAG, "beforeHookMethod 3 zezeze");
beforeCount++;
}
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
super.afterHookedMethod(param);
Log.i(TAG, "afterHookMethod 3 zezeze");
afterCount++;
}
};
@Override
public void hook() {
DexposedBridge.findAndHookMethod(Target.class, "test1", Object.class, int.class, callback1);
DexposedBridge.findAndHookMethod(Target.class, "test1", Object.class, int.class, callback2);
DexposedBridge.findAndHookMethod(Target.class, "test1", Object.class, int.class, callback3);
}
@Override
public boolean validate(Object... args) {
new Target().test1("123", 1);
boolean ret = beforeCount == 3 && afterCount == 3;
// reset.
beforeCount = 0;
afterCount = 0;
return ret;
}
}
================================================
FILE: app/src/main/java/me/weishu/epic/samples/tests/custom/Case13_FastNative.java
================================================
package me.weishu.epic.samples.tests.custom;
import android.util.Log;
import java.lang.reflect.Method;
import de.robv.android.xposed.XposedHelpers;
/**
* Created by weishu on 17/12/13.
*/
public class Case13_FastNative implements Case {
@Override
public void hook() {
// DexposedBridge.findAndHookMethod(Target.class, "longRunMethod", new LogMethodHook());
final Method invoke = XposedHelpers.findMethodExact(Method.class, "invoke", Object.class, Object[].class);
Log.i("mylog", "invole: " + invoke);
}
@Override
public boolean validate(Object... args) {
new Target().longRunMethod();
return true;
}
}
================================================
FILE: app/src/main/java/me/weishu/epic/samples/tests/custom/Case14_GC.java
================================================
package me.weishu.epic.samples.tests.custom;
import de.robv.android.xposed.DexposedBridge;
import me.weishu.epic.samples.tests.LogMethodHook;
import me.weishu.epic.samples.tests.returntype.ReturnTypeTarget;
/**
* Created by weishu on 17/12/13.
*/
public class Case14_GC implements Case {
@Override
public void hook() {
DexposedBridge.findAndHookMethod(ReturnTypeTarget.class, "returnString", String.class, new LogMethodHook());
System.gc();
}
@Override
public boolean validate(Object... args) {
return "123".equals(ReturnTypeTarget.returnString(new String("123")));
}
}
================================================
FILE: app/src/main/java/me/weishu/epic/samples/tests/custom/Case15_StopJit.java
================================================
package me.weishu.epic.samples.tests.custom;
import me.weishu.epic.art.EpicNative;
/**
* Created by weishu on 17/12/13.
*/
public class Case15_StopJit implements Case {
long cookie;
@Override
public void hook() {
cookie = EpicNative.stopJit();
}
@Override
public boolean validate(Object... args) {
EpicNative.startJit(cookie);
return true;
}
}
================================================
FILE: app/src/main/java/me/weishu/epic/samples/tests/custom/Case16_SameEntry.java
================================================
package me.weishu.epic.samples.tests.custom;
import android.util.Log;
import com.taobao.android.dexposed.utility.Debug;
import java.lang.reflect.Method;
import de.robv.android.xposed.DexposedBridge;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XposedHelpers;
import me.weishu.epic.art.method.ArtMethod;
/**
* Created by weishu on 18/1/8.
*/
public class Case16_SameEntry implements Case {
private static final String TAG = "Case16_SameEntry";
@Override
public void hook() {
final Method add = XposedHelpers.findMethodExact(Target.class, "add", int.class, int.class);
final Method plus = XposedHelpers.findMethodExact(Target.class, "plus", int.class, int.class);
ArtMethod artMethod3 = ArtMethod.of(add);
ArtMethod artMethod4 = ArtMethod.of(plus);
Log.i(TAG, "plus: addr: " + Debug.addrHex(artMethod3.getAddress()) + ", entry:"
+ Debug.addrHex(artMethod3.getEntryPointFromQuickCompiledCode()));
Log.i(TAG, "milus: addr: " + Debug.addrHex(artMethod4.getAddress()) + ", entry:"
+ Debug.addrHex(artMethod4.getEntryPointFromQuickCompiledCode()));
DexposedBridge.hookMethod(add, new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
super.beforeHookedMethod(param);
Log.d(TAG, "beforeHookedMethod() called with: param = [" + param + "]");
}
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
super.afterHookedMethod(param);
Log.d(TAG, "afterHookedMethod() called with: param = [" + param + "]");
}
});
DexposedBridge.hookMethod(plus, new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
super.beforeHookedMethod(param);
Log.d(TAG, "beforeHookedMethod() called with: param = [" + param + "]");
}
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
super.afterHookedMethod(param);
Log.d(TAG, "afterHookedMethod() called with: param = [" + param + "]");
}
});
}
@Override
public boolean validate(Object... args) {
Target target = new Target();
int add = target.add(1, 2);
Log.i(TAG, "1 + 2 = " + add);
int plus = target.plus(3, 4);
Log.i(TAG, "3 + 4 = " + plus);
return true;
}
}
================================================
FILE: app/src/main/java/me/weishu/epic/samples/tests/custom/Case17_SameMethod.java
================================================
package me.weishu.epic.samples.tests.custom;
import android.util.Log;
import de.robv.android.xposed.DexposedBridge;
import de.robv.android.xposed.XC_MethodHook;
/**
* Created by weishu on 18/1/11.
*/
public class Case17_SameMethod implements Case {
private static final String TAG = "Case17_SameMethod";
@Override
public void hook() {
DexposedBridge.findAndHookMethod(Target.class, "add", int.class, int.class, new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
super.beforeHookedMethod(param);
Log.d(TAG, "beforeHookedMethod() called with: param = [" + param + "]");
}
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
super.afterHookedMethod(param);
Log.d(TAG, "afterHookedMethod() called with: param = [" + param + "]");
}
});
DexposedBridge.findAndHookMethod(Target.class, "add", int.class, int.class, new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
super.beforeHookedMethod(param);
Log.d(TAG, "beforeHookedMethod2() called with: param = [" + param + "]");
}
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
super.afterHookedMethod(param);
Log.d(TAG, "afterHookedMethod2() called with: param = [" + param + "]");
}
});
}
@Override
public boolean validate(Object... args) {
new Target().add(1, 2);
new Target().add(3, 4);
return false;
}
}
================================================
FILE: app/src/main/java/me/weishu/epic/samples/tests/custom/Case18_returnConst.java
================================================
package me.weishu.epic.samples.tests.custom;
import android.util.Log;
import java.util.Arrays;
import de.robv.android.xposed.DexposedBridge;
import de.robv.android.xposed.XC_MethodHook;
/**
* Created by weishu on 18/1/11.
*/
public class Case18_returnConst implements Case {
private static final String TAG = "Case18_returnConst";
@Override
public void hook() {
DexposedBridge.findAndHookMethod(Target.class, "returnConst", int.class, new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
super.beforeHookedMethod(param);
param.setResult(124);
Log.d(TAG, "beforeHookedMethod() called with: param = [" + Arrays.toString(param.args) + "]");
}
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
super.afterHookedMethod(param);
Log.d(TAG, "afterHookedMethod() called with: param = [" + Arrays.toString(param.args) + "]");
}
});
}
@Override
public boolean validate(Object... args) {
int i = new Target().returnConst(123);
Log.i(TAG, "return : " + i);
return (i == 124);
}
}
================================================
FILE: app/src/main/java/me/weishu/epic/samples/tests/custom/Case2.java
================================================
package me.weishu.epic.samples.tests.custom;
/**
* Created by weishu on 17/11/6.
*/
public class Case2 implements Case{
private static final String TAG = "Case2";
@Override
public void hook() {
// DexposedBridge.findAndHookMethod(Target.class, "add", int.class, int.class, new XC_MethodHook() {
// @Override
// protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
// Log.i(TAG, "before add hooked:" + Arrays.toString(param.args));
// param.setResult(4);
// super.beforeHookedMethod(param);
// }
// });
//
// DexposedBridge.findAndHookMethod(Target.class, "test4", int.class, new XC_MethodHook() {
// @Override
// protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
// super.beforeHookedMethod(param);
// Log.i("mylog", "before", new RuntimeException("stack"));
// Log.i("mylog", "this:" + param.thisObject);
// Log.i("mylog", "method:" + param.method);
// Log.i("mylog", "args:" + Arrays.toString(param.args));
//
// }
//
// @Override
// protected void afterHookedMethod(MethodHookParam param) throws Throwable {
// super.afterHookedMethod(param);
// Log.i("mylog", "after");
// }
// });
}
@Override
public boolean validate(Object... args) {
// Log.i(TAG, "1 + 2: " + Target.add(1, 2));
// return Target.add(1, 2) == 4;
Target.validate();
return true;
}
}
================================================
FILE: app/src/main/java/me/weishu/epic/samples/tests/custom/Case3.java
================================================
package me.weishu.epic.samples.tests.custom;
import android.util.Log;
import de.robv.android.xposed.DexposedBridge;
import de.robv.android.xposed.XC_MethodHook;
/**
* Created by weishu on 17/11/6.
*/
public class Case3 implements Case {
private static final String TAG = "Case3";
@Override
public void hook() {
DexposedBridge.findAndHookMethod(System.class, "currentTimeMillis", new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
super.beforeHookedMethod(param);
Log.i("mylog", "before currentTimeMillis");
}
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
super.afterHookedMethod(param);
Log.i("mylog", "after currentTimeMillis");
}
});
}
@Override
public boolean validate(Object... args) {
Log.i(TAG, "currentTimeMillis: " + System.currentTimeMillis());
return true;
}
}
================================================
FILE: app/src/main/java/me/weishu/epic/samples/tests/custom/Case4.java
================================================
package me.weishu.epic.samples.tests.custom;
import android.text.TextUtils;
import android.util.Log;
import de.robv.android.xposed.DexposedBridge;
import de.robv.android.xposed.XC_MethodHook;
/**
* Created by weishu on 17/11/6.
*/
public class Case4 implements Case {
private static final String TAG = "Case4";
@Override
public void hook() {
DexposedBridge.findAndHookMethod(TextUtils.class, "equals", CharSequence.class, CharSequence.class, new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
Log.i(TAG, "beforeHookedMethod: this:" + param.thisObject, new RuntimeException("stack"));
Log.i(TAG, "beforeHookedMethod: String1:" + param.args[0]);
Log.i(TAG, "beforeHookedMethod: String2:" + param.args[1]);
param.setResult(false);
super.beforeHookedMethod(param);
}
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
super.afterHookedMethod(param);
}
});
}
@Override
public boolean validate(Object... args) {
String a1 = new String("123");
String a2 = new String("123");
Log.i(TAG, " '123' equals '123' ? " + TextUtils.equals(a1, a2));
return true;
}
}
================================================
FILE: app/src/main/java/me/weishu/epic/samples/tests/custom/Case5.java
================================================
package me.weishu.epic.samples.tests.custom;
import android.util.Log;
import android.widget.TextView;
import com.taobao.android.dexposed.utility.Unsafe;
import java.lang.reflect.Method;
import de.robv.android.xposed.DexposedBridge;
import de.robv.android.xposed.XC_MethodHook;
import me.weishu.epic.art.EpicNative;
/**
* Created by weishu on 17/11/6.
*/
public class Case5 implements Case {
@Override
public void hook() {
DexposedBridge.findAndHookMethod(TextView.class, "setPadding", int.class, int.class, int.class, int.class, new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
super.beforeHookedMethod(param);
if (param.thisObject != null) {
Log.i("mylog", "this:" + Long.toHexString(Unsafe.getObjectAddress(param.thisObject)));
}
if (param.method != null) {
Log.i("mylog", "mehod:" + Long.toHexString(EpicNative.getMethodAddress((Method) param.method)));
}
if (param.args != null) {
for (Object arg : param.args) {
Log.i("mylog", "param:" + arg);
if (arg != null) {
Log.i("mylog", "<" + arg.getClass() + "> : 0x" +
Long.toHexString(Unsafe.getObjectAddress(arg)) + ", value: " + arg);
} else {
Log.i("mylog", "param: null");
}
}
}
}
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
super.afterHookedMethod(param);
Log.i("mylog", "after");
}
});
}
@Override
public boolean validate(Object... args) {
return true;
}
}
================================================
FILE: app/src/main/java/me/weishu/epic/samples/tests/custom/Case6.java
================================================
package me.weishu.epic.samples.tests.custom;
import android.os.SystemClock;
import android.util.Log;
import com.taobao.android.dexposed.utility.Debug;
import com.taobao.android.dexposed.utility.Unsafe;
import java.lang.reflect.Method;
import de.robv.android.xposed.XposedHelpers;
import me.weishu.epic.art.EpicNative;
import me.weishu.epic.art.method.ArtMethod;
/**
* Created by weishu on 17/11/6.
*/
public class Case6 implements Case {
private static final String TAG = "Case6";
@Override
public void hook() {
Object test = new Object();
Log.i(TAG, "test object:" + test);
long testAddr = Unsafe.getObjectAddress(test);
Log.i(TAG, "test object address :" + testAddr);
Log.i(TAG, "test object :" + EpicNative.getObject(XposedHelpers.getLongField(Thread.currentThread(), "nativePeer"), testAddr));
// Log.i(TAG, "object:" + EpicNative.getObject())
final Method nanoTime = XposedHelpers.findMethodExact(System.class, "nanoTime");
final Method uptimeMillis = XposedHelpers.findMethodExact(SystemClock.class, "uptimeMillis");
final Method map = XposedHelpers.findMethodExact(Target.class, "test1", Object.class, int.class);
final Method malloc = XposedHelpers.findMethodExact(Target.class, "test3", Object.class, int.class);
ArtMethod artMethod1 = ArtMethod.of(nanoTime);
ArtMethod artMethod2 = ArtMethod.of(uptimeMillis);
ArtMethod artMethod3 = ArtMethod.of(map);
ArtMethod artMethod4 = ArtMethod.of(malloc);
Log.i(TAG, "nanoTime: addr: 0x" + artMethod1.getAddress() + ", entry:" + Debug.addrHex(artMethod1.getEntryPointFromQuickCompiledCode()));
Log.i(TAG, "uptimeMills: addr: 0x" + artMethod2.getAddress() + ", entry:" + Debug.addrHex(artMethod2.getEntryPointFromQuickCompiledCode()));
Log.i(TAG, "map : addr: 0x" + artMethod3.getAddress() + ", entry:" + Debug.addrHex(artMethod3.getEntryPointFromQuickCompiledCode()));
Log.i(TAG, "malloc: addr: 0x" + artMethod4.getAddress() + ", entry:" + Debug.addrHex(artMethod4.getEntryPointFromQuickCompiledCode()));
}
@Override
public boolean validate(Object... args) {
return true;
}
}
================================================
FILE: app/src/main/java/me/weishu/epic/samples/tests/custom/Case7.java
================================================
package me.weishu.epic.samples.tests.custom;
import android.util.Log;
import java.util.Arrays;
import de.robv.android.xposed.DexposedBridge;
import de.robv.android.xposed.XC_MethodHook;
/**
* Created by weishu on 17/11/8.
*/
public class Case7 implements Case {
private static final String TAG = "Case7";
@Override
public void hook() {
Log.i(TAG, "hook test1");
DexposedBridge.findAndHookMethod(Target.class, "test1", Object.class, int.class, new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
Log.i(TAG, "before add hooked:" + Arrays.toString(param.args));
param.setResult(4);
super.beforeHookedMethod(param);
}
});
}
@Override
public boolean validate(Object... args) {
Target t = new Target();
t.test1(t, 123);
return true;
}
}
================================================
FILE: app/src/main/java/me/weishu/epic/samples/tests/custom/Case8_Activity_onCreate.java
================================================
package me.weishu.epic.samples.tests.custom;
import android.os.Bundle;
import android.util.Log;
import de.robv.android.xposed.DexposedBridge;
import de.robv.android.xposed.XC_MethodHook;
import me.weishu.epic.samples.MainActivity;
/**
* Created by weishu on 17/11/9.
*/
public class Case8_Activity_onCreate implements Case {
private static final String TAG = "Case8_Activity_onCreate";
@Override
public void hook() {
DexposedBridge.findAndHookMethod(MainActivity.class, "onCreate", Bundle.class, new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
super.beforeHookedMethod(param);
Log.i(TAG, "before hooked");
if (param.args[0] == null) {
param.args[0] = new Bundle();
}
Bundle b = (Bundle) param.args[0];
Log.i(TAG, "bundle: " + param.args[0]);
b.putString("hehe", "hacked");
}
});
}
@Override
public boolean validate(Object... args) {
return true;
}
}
================================================
FILE: app/src/main/java/me/weishu/epic/samples/tests/custom/Case9_ThreadMonitor.java
================================================
package me.weishu.epic.samples.tests.custom;
import android.util.Log;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import de.robv.android.xposed.DexposedBridge;
import de.robv.android.xposed.XC_MethodHook;
/**
* Created by weishu on 17/11/10.
*/
public class Case9_ThreadMonitor implements Case {
private static final String TAG = "Case9_ThreadMonitor";
@Override
public void hook() {
try {
class ThreadMethodHook extends XC_MethodHook {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
super.beforeHookedMethod(param);
Thread t = (Thread) param.thisObject;
Log.i(TAG, "thread:" + t + ", started..");
}
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
super.afterHookedMethod(param);
Thread t = (Thread) param.thisObject;
Log.i(TAG, "thread:" + t + ", exit..");
}
}
DexposedBridge.hookAllConstructors(Thread.class, new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
super.afterHookedMethod(param);
Thread thread = (Thread) param.thisObject;
Class<?> clazz = thread.getClass();
if (clazz != Thread.class) {
Log.d(TAG, "found class extend Thread:" + clazz);
DexposedBridge.findAndHookMethod(clazz, "run", new ThreadMethodHook());
}
Log.d(TAG, "Thread: " + thread.getName() + " class:" + thread.getClass() + " is created.");
}
});
DexposedBridge.findAndHookMethod(Thread.class, "run", new ThreadMethodHook());
} catch (Throwable e) {
Log.e(TAG, "hook failed", e);
}
}
@Override
public boolean validate(Object... args) {
new Thread(new Runnable() {
@Override
public void run() {
Log.i(TAG, "I am started..");
}
}).start();
new MyThread().start();
final ExecutorService executorService = Executors.newCachedThreadPool();
for (int i = 0; i < 4; i++) {
// final int num = i;
executorService.execute(new Runnable() {
@Override
public void run() {
Log.i(TAG, " lalala");
}
});
}
return true;
}
static class MyThread extends Thread {
@Override
public void run() {
Log.i(TAG, "dang dang dang..");
}
}
}
================================================
FILE: app/src/main/java/me/weishu/epic/samples/tests/custom/CaseManager.java
================================================
package me.weishu.epic.samples.tests.custom;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
/**
* Created by weishu on 17/11/6.
*/
public class CaseManager {
private static volatile CaseManager INSTANCE = new CaseManager();
private Map<Class<?>, Case> caseMap = new ConcurrentHashMap<>();
public static synchronized CaseManager getInstance() {
return INSTANCE;
}
public synchronized Case getCase(Class<?> clazz) {
Case caze = caseMap.get(clazz);
if (caze != null) {
return caze;
} else {
try {
caze = (Case) clazz.newInstance();
caseMap.put(clazz, caze);
} catch (Throwable e) {
throw new RuntimeException("can not get case !!", e);
}
}
return caze;
}
public synchronized Set<Class<?>> getCases() {
return caseMap.keySet();
}
}
================================================
FILE: app/src/main/java/me/weishu/epic/samples/tests/custom/Target.java
================================================
package me.weishu.epic.samples.tests.custom;
import android.os.SystemClock;
import android.util.Log;
import java.lang.reflect.Method;
import de.robv.android.xposed.XposedHelpers;
import me.weishu.epic.art.method.ArtMethod;
/**
* Created by weishu on 17/11/3.
*/
public class Target {
public Target() {
}
public int test1(Object a, int b) {
Log.i("mylog", "test1, arg1: " + a + " , arg2:" + b);
new Runnable() {
@Override
public void run() {
final Method enclosingMethod = getClass().getEnclosingMethod();
long entry = ArtMethod.of(enclosingMethod).getEntryPointFromQuickCompiledCode();
if (entry != ArtMethod.getQuickToInterpreterBridge()) {
Log.w("mylog", "method compiled....");
}
Log.i("mylog", enclosingMethod + "entry: point: 0x" + Long.toHexString(entry));
}
}.run();
return a.hashCode() + b;
}
public int returnConst(int a) {
return a;
}
public int add(int a, int b) {
return a + b;
}
public int plus(int a, int b) {
return a + b;
}
public int test3(Object a, int b) {
Log.i("mylog", "test1, arg1: " + a + " , arg2:" + b);
return a.hashCode() + b;
}
public static int test4(int a) {
return Integer.valueOf(a).hashCode();
}
public static float add(int a, float b) {
return a + b;
}
public static int test2(Object a, int b) {
Log.i("mylog", "test1, arg1: " + a + " , arg2:" + b);
return a.hashCode() + b;
}
public long longRunMethod() {
SystemClock.sleep(4000);
return SystemClock.elapsedRealtime();
}
public static void validate() {
final Method validate = XposedHelpers.findMethodExact(Target.class, "validate");
long entry = ArtMethod.of(validate).getEntryPointFromQuickCompiledCode();
if (entry != ArtMethod.getQuickToInterpreterBridge()) {
Log.w("mylog", "method compiled....");
new Target().test1("123", 1);
}
Log.i("mylog", validate + "entry: point: 0x" + Long.toHexString(entry));
}
}
================================================
FILE: app/src/main/java/me/weishu/epic/samples/tests/invoketype/InvokeConstructor.java
================================================
package me.weishu.epic.samples.tests.invoketype;
import de.robv.android.xposed.DexposedBridge;
import de.robv.android.xposed.XposedHelpers;
import me.weishu.epic.samples.tests.LogMethodHook;
import me.weishu.epic.samples.tests.TestCase;
/**
* Created by weishu on 17/11/14.
*/
public class InvokeConstructor extends TestCase {
boolean callBefore = false;
boolean callAfter = false;
public InvokeConstructor() {
super("Constructor");
}
@Override
public void test() {
DexposedBridge.hookMethod(XposedHelpers.findConstructorExact(InvokeTypeTarget.class), new LogMethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
super.beforeHookedMethod(param);
callBefore = true;
}
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
super.afterHookedMethod(param);
callAfter = true;
}
});
}
@Override
public boolean predicate() {
new InvokeTypeTarget();
return callBefore && callAfter;
}
}
================================================
FILE: app/src/main/java/me/weishu/epic/samples/tests/invoketype/InvokeTypeTarget.java
================================================
package me.weishu.epic.samples.tests.invoketype;
/**
* Created by weishu on 17/11/14.
*/
public class InvokeTypeTarget {
}
================================================
FILE: app/src/main/java/me/weishu/epic/samples/tests/returntype/BooleanType.java
================================================
package me.weishu.epic.samples.tests.returntype;
import de.robv.android.xposed.DexposedBridge;
import me.weishu.epic.samples.tests.LogMethodHook;
import me.weishu.epic.samples.tests.TestCase;
/**
* Created by weishu on 17/11/13.
*/
public class BooleanType extends TestCase {
final boolean returnType = Boolean.FALSE;
final boolean returnTypeModified = !returnType;
public BooleanType() {
super("Boolean");
}
@Override
public void test() {
DexposedBridge.findAndHookMethod(ReturnTypeTarget.class, "returnBoolean", boolean.class, new LogMethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
param.setResult(returnTypeModified);
super.beforeHookedMethod(param);
}
});
}
@Override
public boolean predicate() {
return ReturnTypeTarget.returnBoolean(returnType) == returnTypeModified;
}
}
================================================
FILE: app/src/main/java/me/weishu/epic/samples/tests/returntype/ByteType.java
================================================
package me.weishu.epic.samples.tests.returntype;
import de.robv.android.xposed.DexposedBridge;
import me.weishu.epic.samples.tests.LogMethodHook;
import me.weishu.epic.samples.tests.TestCase;
/**
* Created by weishu on 17/11/13.
*/
public class ByteType extends TestCase {
final byte returnType = Byte.MAX_VALUE;
final byte returnTypeModified = Byte.MAX_VALUE - 1;
public ByteType() {
super("Byte");
}
@Override
public void test() {
DexposedBridge.findAndHookMethod(ReturnTypeTarget.class, "returnByte", byte.class, new LogMethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
param.setResult(returnTypeModified);
super.beforeHookedMethod(param);
}
});
}
@Override
public boolean predicate() {
final byte raw = ReturnTypeTarget.returnByte(returnType);
return raw == returnTypeModified;
}
}
================================================
FILE: app/src/main/java/me/weishu/epic/samples/tests/returntype/CharType.java
================================================
package me.weishu.epic.samples.tests.returntype;
import de.robv.android.xposed.DexposedBridge;
import me.weishu.epic.samples.tests.LogMethodHook;
import me.weishu.epic.samples.tests.TestCase;
/**
* Created by weishu on 17/11/13.
*/
public class CharType extends TestCase {
final char returnType = Character.MAX_VALUE;
final char returnTypeModified = returnType - 1;
public CharType() {
super("Char");
}
@Override
public void test() {
DexposedBridge.findAndHookMethod(ReturnTypeTarget.class, "returnChar", char.class, new LogMethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
param.setResult(returnTypeModified);
super.beforeHookedMethod(param);
}
});
}
@Override
public boolean predicate() {
return ReturnTypeTarget.returnChar(returnType) == returnTypeModified;
}
}
================================================
FILE: app/src/main/java/me/weishu/epic/samples/tests/returntype/CustomType.java
================================================
package me.weishu.epic.samples.tests.returntype;
import de.robv.android.xposed.DexposedBridge;
import me.weishu.epic.samples.tests.LogMethodHook;
import me.weishu.epic.samples.tests.TestCase;
/**
* Created by weishu on 17/11/13.
*/
public class CustomType extends TestCase {
final ReturnTypeTarget returnType = new ReturnTypeTarget();
final ReturnTypeTarget returnTypeModified = new ReturnTypeTarget();
public CustomType() {
super("Custom");
}
@Override
public void test() {
DexposedBridge.findAndHookMethod(ReturnTypeTarget.class, "returnCustom", ReturnTypeTarget.class, new LogMethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
param.setResult(returnTypeModified);
super.beforeHookedMethod(param);
}
});
}
@Override
public boolean predicate() {
return ReturnTypeTarget.returnCustom(returnType) == returnTypeModified;
}
}
================================================
FILE: app/src/main/java/me/weishu/epic/samples/tests/returntype/DoubleType.java
================================================
package me.weishu.epic.samples.tests.returntype;
import de.robv.android.xposed.DexposedBridge;
import me.weishu.epic.samples.tests.LogMethodHook;
import me.weishu.epic.samples.tests.TestCase;
/**
* Created by weishu on 17/11/13.
*/
public class DoubleType extends TestCase {
final double returnType = 12343748.12435;
final double returnTypeModified = returnType - 1;
public DoubleType() {
super("Double");
}
@Override
public void test() {
DexposedBridge.findAndHookMethod(ReturnTypeTarget.class, "returnDouble", double.class, new LogMethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
param.setResult(returnTypeModified);
super.beforeHookedMethod(param);
}
});
}
@Override
public boolean predicate() {
return ReturnTypeTarget.returnDouble(returnType) == returnTypeModified;
}
}
================================================
FILE: app/src/main/java/me/weishu/epic/samples/tests/returntype/FloatType.java
================================================
package me.weishu.epic.samples.tests.returntype;
import de.robv.android.xposed.DexposedBridge;
import me.weishu.epic.samples.tests.LogMethodHook;
import me.weishu.epic.samples.tests.TestCase;
/**
* Created by weishu on 17/11/13.
*/
public class FloatType extends TestCase {
final float returnType = 12545.212f;
final float returnTypeModified = returnType - 1;
public FloatType() {
super("Float");
}
@Override
public void test() {
DexposedBridge.findAndHookMethod(ReturnTypeTarget.class, "returnFloat", float.class, new LogMethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
param.setResult(returnTypeModified);
super.beforeHookedMethod(param);
}
});
}
@Override
public boolean predicate() {
return ReturnTypeTarget.returnFloat(returnType) == returnTypeModified;
}
}
================================================
FILE: app/src/main/java/me/weishu/epic/samples/tests/returntype/IntType.java
================================================
package me.weishu.epic.samples.tests.returntype;
import de.robv.android.xposed.DexposedBridge;
import me.weishu.epic.samples.tests.LogMethodHook;
import me.weishu.epic.samples.tests.TestCase;
/**
* Created by weishu on 17/11/13.
*/
public class IntType extends TestCase {
final int returnType = Integer.MAX_VALUE;
final int returnTypeModified = returnType - 1;
public IntType() {
super("Int");
}
@Override
public void test() {
DexposedBridge.findAndHookMethod(ReturnTypeTarget.class, "returnInt", int.class, new LogMethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
param.setResult(returnTypeModified);
super.beforeHookedMethod(param);
}
});
}
@Override
public boolean predicate() {
final int i = ReturnTypeTarget.returnInt(returnType);
return i == returnTypeModified;
}
}
================================================
FILE: app/src/main/java/me/weishu/epic/samples/tests/returntype/LongType.java
================================================
package me.weishu.epic.samples.tests.returntype;
import de.robv.android.xposed.DexposedBridge;
import me.weishu.epic.samples.tests.LogMethodHook;
import me.weishu.epic.samples.tests.TestCase;
/**
* Created by weishu on 17/11/13.
*/
public class LongType extends TestCase {
final long returnType = Long.MAX_VALUE / 2;
final long returnTypeModified = returnType - 1;
public LongType() {
super("Long");
}
@Override
public void test() {
DexposedBridge.findAndHookMethod(ReturnTypeTarget.class, "returnLong", long.class, new LogMethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
param.setResult(returnTypeModified);
super.beforeHookedMethod(param);
}
});
}
@Override
public boolean predicate() {
return ReturnTypeTarget.returnLong(returnType) == returnTypeModified;
}
}
================================================
FILE: app/src/main/java/me/weishu/epic/samples/tests/returntype/ReturnTypeTarget.java
================================================
package me.weishu.epic.samples.tests.returntype;
import android.util.Log;
/**
* Created by weishu on 17/11/13.
*/
public class ReturnTypeTarget {
private static final String TAG = "ReturnTypeTarget";
public static void returnVoid() {
Log.d(TAG, "returnVoid() called");
}
public static byte returnByte(byte b) {
Log.i(TAG, "returnByte() called");
return b;
}
public static char returnChar(char c) {
Log.i(TAG, "returnChar() called");
return c;
}
public static short returnShort(short s) {
Log.i(TAG, "returnShort() called");
return s;
}
public static int returnInt(int i) {
Log.i(TAG, "returnInt() called");
return i;
}
public static long returnLong(long l) {
Log.i(TAG, "returnLong() called");
return l;
}
public static float returnFloat(float f) {
Log.i(TAG, "returnFloat() called");
return f;
}
public static double returnDouble(double d) {
Log.i(TAG, "returnDouble() called");
return d;
}
public static boolean returnBoolean(boolean b) {
Log.i(TAG, "returnBoolean() called");
return b;
}
public static String returnString(String s) {
Log.i(TAG, "returnString() called with: s = [" + s + "]");
return s;
}
public static String[] returnStringArray(String[] a) {
Log.i(TAG, "returnStringArray() called with: a = [" + a + "]");
return a;
}
public static ReturnTypeTarget returnCustom(ReturnTypeTarget r) {
Log.i(TAG, "returnCustom() called with: r = [" + r + "]");
return r;
}
}
================================================
FILE: app/src/main/java/me/weishu/epic/samples/tests/returntype/ShortType.java
================================================
package me.weishu.epic.samples.tests.returntype;
import de.robv.android.xposed.DexposedBridge;
import me.weishu.epic.samples.tests.LogMethodHook;
import me.weishu.epic.samples.tests.TestCase;
/**
* Created by weishu on 17/11/13.
*/
public class ShortType extends TestCase {
final short returnType = Short.MAX_VALUE / 2;
final short returnTypeModified = returnType - 1;
public ShortType() {
super("Short");
}
@Override
public void test() {
DexposedBridge.findAndHookMethod(ReturnTypeTarget.class, "returnShort", short.class, new LogMethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
param.setResult(returnTypeModified);
super.beforeHookedMethod(param);
}
});
}
@Override
public boolean predicate() {
return ReturnTypeTarget.returnShort(returnType) == returnTypeModified;
}
}
================================================
FILE: app/src/main/java/me/weishu/epic/samples/tests/returntype/StringArrayType.java
================================================
package me.weishu.epic.samples.tests.returntype;
import de.robv.android.xposed.DexposedBridge;
import me.weishu.epic.samples.tests.LogMethodHook;
import me.weishu.epic.samples.tests.TestCase;
/**
* Created by weishu on 17/11/13.
*/
public class StringArrayType extends TestCase {
final String[] returnType = new String[]{"123", "456"};
final String[] returnTypeModified = new String[]{"123", "456", "678"};
public StringArrayType() {
super("StringArray");
}
@Override
public void test() {
DexposedBridge.findAndHookMethod(ReturnTypeTarget.class, "returnStringArray", String[].class, new LogMethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
param.setResult(returnTypeModified);
super.beforeHookedMethod(param);
}
});
}
@Override
public boolean predicate() {
return ReturnTypeTarget.returnStringArray(returnType) == returnTypeModified;
}
}
================================================
FILE: app/src/main/java/me/weishu/epic/samples/tests/returntype/StringType.java
================================================
package me.weishu.epic.samples.tests.returntype;
import de.robv.android.xposed.DexposedBridge;
import me.weishu.epic.samples.tests.LogMethodHook;
import me.weishu.epic.samples.tests.TestCase;
/**
* Created by weishu on 17/11/13.
*/
public class StringType extends TestCase {
final String returnType = "123455";
final String returnTypeModified = "784fsgiulfodsg";
public StringType() {
super("String");
}
@Override
public void test() {
DexposedBridge.findAndHookMethod(ReturnTypeTarget.class, "returnString", String.class, new LogMethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
param.setResult(returnTypeModified);
super.beforeHookedMethod(param);
}
});
}
@Override
public boolean predicate() {
return ReturnTypeTarget.returnString(returnType).equals(returnTypeModified);
}
}
================================================
FILE: app/src/main/java/me/weishu/epic/samples/tests/returntype/VoidType.java
================================================
package me.weishu.epic.samples.tests.returntype;
import android.util.Log;
import de.robv.android.xposed.DexposedBridge;
import de.robv.android.xposed.XC_MethodHook;
import me.weishu.epic.samples.tests.TestCase;
/**
* Created by weishu on 17/11/13.
*/
public class VoidType extends TestCase {
private static final String TAG = "VoidType";
boolean callBefore = false;
boolean callAfter = false;
public VoidType() {
super("无返回值");
}
@Override
public void test() {
DexposedBridge.findAndHookMethod(ReturnTypeTarget.class, "returnVoid", new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
super.beforeHookedMethod(param);
callBefore = true;
}
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
super.afterHookedMethod(param);
callAfter = true;
}
});
}
@Override
public boolean predicate() {
ReturnTypeTarget.returnVoid();
Log.i(TAG, "callBefore:" + callBefore + ", callAfter:" + callAfter);
return callBefore && callAfter;
}
}
================================================
FILE: app/src/main/res/layout/activity_main.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<ExpandableListView
android:groupIndicator="@null"
android:id="@+id/list"
android:childDivider="@drawable/qmui_divider"
android:layout_width="match_parent"
android:layout_height="match_parent">
</ExpandableListView>
</LinearLayout>
================================================
FILE: app/src/main/res/layout/child_layout.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:paddingLeft="20dp"
android:background="@color/qmui_config_color_background"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/validate"
android:text="validate"
android:layout_alignParentRight="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<Button
android:id="@+id/test"
android:text="test"
android:layout_toLeftOf="@+id/validate"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:layout_alignParentLeft="true"
android:id="@+id/label"
android:gravity="center"
android:layout_centerVertical="true"
android:textSize="12sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</RelativeLayout>
================================================
FILE: app/src/main/res/layout/parent_layout.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:layout_marginRight="20dp"
android:layout_centerVertical="true"
android:src="@drawable/arrow_down"
android:id="@+id/indicator"
android:layout_width="16dp"
android:layout_height="10dp"
android:layout_alignParentRight="true" />
<TextView
android:id="@+id/text"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_alignParentLeft="true"
android:layout_toLeftOf="@+id/indicator"
android:paddingBottom="12dp"
android:paddingLeft="20dp"
android:paddingTop="12dp"
android:textSize="20sp" />
</RelativeLayout>
================================================
FILE: app/src/main/res/values/colors.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#3F51B5</color>
<color name="colorPrimaryDark">#303F9F</color>
<color name="colorAccent">#FF4081</color>
</resources>
================================================
FILE: app/src/main/res/values/strings.xml
================================================
<resources>
<string name="app_name">epic</string>
</resources>
================================================
FILE: app/src/main/res/values/styles.xml
================================================
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="android:Theme.Holo.Light.DarkActionBar">
<!-- Customize your theme here. -->
</style>
</resources>
================================================
FILE: app/src/test/java/me/weishu/epic/ExampleUnitTest.java
================================================
//package me.weishu.epic;
//
//import org.junit.Test;
//
//import static org.junit.Assert.*;
//
///**
// * Example local unit test, which will execute on the development machine (host).
// *
// * @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
// */
//public class ExampleUnitTest {
// @Test
// public void addition_isCorrect() throws Exception {
// assertEquals(4, 2 + 2);
// }
//}
================================================
FILE: build.gradle
================================================
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
jcenter()
maven {
url 'https://maven.google.com/'
name 'Google'
}
}
dependencies {
classpath 'com.android.tools.build:gradle:4.2.1'
classpath 'com.github.panpf.bintray-publish:bintray-publish:1.0.0'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
mavenLocal()
jcenter()
maven {
url 'https://maven.google.com/'
name 'Google'
}
maven { url 'https://jitpack.io' }
}
tasks.withType(Javadoc) {
enabled = false
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
================================================
FILE: gradle/wrapper/gradle-wrapper.properties
================================================
#Tue Nov 07 13:44:26 CST 2017
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.7.1-all.zip
================================================
FILE: gradle.properties
================================================
## Project-wide Gradle settings.
#
# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
#
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
# Default value: -Xmx1024m -XX:MaxPermSize=256m
# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
#
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
================================================
FILE: gradlew
================================================
#!/usr/bin/env bash
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn ( ) {
echo "$*"
}
die ( ) {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
esac
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
function splitJvmOpts() {
JVM_OPTS=("$@")
}
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
================================================
FILE: gradlew.bat
================================================
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windowz variants
if not "%OS%" == "Windows_NT" goto win9xME_args
if "%@eval[2+2]" == "4" goto 4NT_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
goto execute
:4NT_args
@rem Get arguments from the 4NT Shell from JP Software
set CMD_LINE_ARGS=%$
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega
================================================
FILE: library/.gitignore
================================================
/build
================================================
FILE: library/CMakeCache.txt
================================================
# This is the CMakeCache file.
# For build in directory: /Users/weishu/dev/space/arthook/epic/library
# It was generated by CMake: /usr/local/Cellar/cmake/3.9.1/bin/cmake
# You can edit this file to change values found and used by cmake.
# If you do not want to change any of the values, simply exit the editor.
# If you do want to change a value, simply edit, save, and exit the editor.
# The syntax for the file is as follows:
# KEY:TYPE=VALUE
# KEY is the name of a variable in the cache.
# TYPE is a hint to GUIs for the type of VALUE, DO NOT EDIT TYPE!.
# VALUE is the current value for the KEY.
########################
# EXTERNAL cache entries
########################
//No help, variable specified on the command line.
ANDROID_TOOLCHAIN:UNINITIALIZED=gcc
//Path to a program.
CMAKE_AR:FILEPATH=/Users/weishu/Library/Android/sdk/ndk-bundle/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64/bin/arm-linux-androideabi-ar
//Choose the type of build, options are: None(CMAKE_CXX_FLAGS or
// CMAKE_C_FLAGS used) Debug Release RelWithDebInfo MinSizeRel.
CMAKE_BUILD_TYPE:STRING=Debug
//Enable/Disable color output during build.
CMAKE_COLOR_MAKEFILE:BOOL=ON
//A wrapper around 'ar' adding the appropriate '--plugin' option
// for the GCC compiler
CMAKE_CXX_COMPILER_AR:FILEPATH=/Users/weishu/Library/Android/sdk/ndk-bundle/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64/bin/arm-linux-androideabi-gcc-ar
//A wrapper around 'ranlib' adding the appropriate '--plugin' option
// for the GCC compiler
CMAKE_CXX_COMPILER_RANLIB:FILEPATH=/Users/weishu/Library/Android/sdk/ndk-bundle/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64/bin/arm-linux-androideabi-gcc-ranlib
//Flags used by the compiler during all build types.
CMAKE_CXX_FLAGS:STRING=
//Flags used by the compiler during debug builds.
CMAKE_CXX_FLAGS_DEBUG:STRING=
//Flags used by the compiler during release builds for minimum
// size.
CMAKE_CXX_FLAGS_MINSIZEREL:STRING=-Os -DNDEBUG
//Flags used by the compiler during release builds.
CMAKE_CXX_FLAGS_RELEASE:STRING=
//Flags used by the compiler during release builds with debug info.
CMAKE_CXX_FLAGS_RELWITHDEBINFO:STRING=-O2 -g -DNDEBUG
//Libraries linked by default with all C++ applications.
CMAKE_CXX_STANDARD_LIBRARIES:STRING=-lm "/Users/weishu/Library/Android/sdk/ndk-bundle/sources/cxx-stl/gnu-libstdc++/4.9/libs/armeabi-v7a/libgnustl_static.a"
//A wrapper around 'ar' adding the appropriate '--plugin' option
// for the GCC compiler
CMAKE_C_COMPILER_AR:FILEPATH=/Users/weishu/Library/Android/sdk/ndk-bundle/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64/bin/arm-linux-androideabi-gcc-ar
//A wrapper around 'ranlib' adding the appropriate '--plugin' option
// for the GCC compiler
CMAKE_C_COMPILER_RANLIB:FILEPATH=/Users/weishu/Library/Android/sdk/ndk-bundle/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64/bin/arm-linux-androideabi-gcc-ranlib
//Flags used by the compiler during all build types.
CMAKE_C_FLAGS:STRING=
//Flags used by the compiler during debug builds.
CMAKE_C_FLAGS_DEBUG:STRING=
//Flags used by the compiler during release builds for minimum
// size.
CMAKE_C_FLAGS_MINSIZEREL:STRING=-Os -DNDEBUG
//Flags used by the compiler during release builds.
CMAKE_C_FLAGS_RELEASE:STRING=
//Flags used by the compiler during release builds with debug info.
CMAKE_C_FLAGS_RELWITHDEBINFO:STRING=-O2 -g -DNDEBUG
//Libraries linked by default with all C applications.
CMAKE_C_STANDARD_LIBRARIES:STRING=-lm
//Flags used by the linker.
CMAKE_EXE_LINKER_FLAGS:STRING=
//Flags used by the linker during debug builds.
CMAKE_EXE_LINKER_FLAGS_DEBUG:STRING=
//Flags used by the linker during release minsize builds.
CMAKE_EXE_LINKER_FLAGS_MINSIZEREL:STRING=
//Flags used by the linker during release builds.
CMAKE_EXE_LINKER_FLAGS_RELEASE:STRING=
//Flags used by the linker during Release with Debug Info builds.
CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO:STRING=
//Enable/Disable output of compile commands during generation.
CMAKE_EXPORT_COMPILE_COMMANDS:BOOL=OFF
//Install path prefix, prepended onto install directories.
CMAKE_INSTALL_PREFIX:PATH=/usr/local
//Path to a program.
CMAKE_LINKER:FILEPATH=/Users/weishu/Library/Android/sdk/ndk-bundle/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64/bin/arm-linux-androideabi-ld
//Path to a program.
CMAKE_MAKE_PROGRAM:FILEPATH=/opt/local/bin/gmake
//Flags used by the linker during the creation of modules.
CMAKE_MODULE_LINKER_FLAGS:STRING=
//Flags used by the linker during debug builds.
CMAKE_MODULE_LINKER_FLAGS_DEBUG:STRING=
//Flags used by the linker during release minsize builds.
CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL:STRING=
//Flags used by the linker during release builds.
CMAKE_MODULE_LINKER_FLAGS_RELEASE:STRING=
//Flags used by the linker during Release with Debug Info builds.
CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO:STRING=
//Path to a program.
CMAKE_NM:FILEPATH=/Users/weishu/Library/Android/sdk/ndk-bundle/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64/bin/arm-linux-androideabi-nm
//Path to a program.
CMAKE_OBJCOPY:FILEPATH=/Users/weishu/Library/Android/sdk/ndk-bundle/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64/bin/arm-linux-androideabi-objcopy
//Path to a program.
CMAKE_OBJDUMP:FILEPATH=/Users/weishu/Library/Android/sdk/ndk-bundle/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64/bin/arm-linux-androideabi-objdump
//Value Computed by CMake
CMAKE_PROJECT_NAME:STATIC=Project
//Path to a program.
CMAKE_RANLIB:FILEPATH=/Users/weishu/Library/Android/sdk/ndk-bundle/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64/bin/arm-linux-androideabi-ranlib
//Flags used by the linker during the creation of dll's.
CMAKE_SHARED_LINKER_FLAGS:STRING=
//Flags used by the linker during debug builds.
CMAKE_SHARED_LINKER_FLAGS_DEBUG:STRING=
//Flags used by the linker during release minsize builds.
CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL:STRING=
//Flags used by the linker during release builds.
CMAKE_SHARED_LINKER_FLAGS_RELEASE:STRING=
//Flags used by the linker during Release with Debug Info builds.
CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO:STRING=
//If set, runtime paths are not added when installing shared libraries,
// but are added when building.
CMAKE_SKIP_INSTALL_RPATH:BOOL=NO
//If set, runtime paths are not added when using shared libraries.
CMAKE_SKIP_RPATH:BOOL=NO
//Flags used by the linker during the creation of static libraries.
CMAKE_STATIC_LINKER_FLAGS:STRING=
//Flags used by the linker during debug builds.
CMAKE_STATIC_LINKER_FLAGS_DEBUG:STRING=
//Flags used by the linker during release minsize builds.
CMAKE_STATIC_LINKER_FLAGS_MINSIZEREL:STRING=
//Flags used by the linker during release builds.
CMAKE_STATIC_LINKER_FLAGS_RELEASE:STRING=
//Flags used by the linker during Release with Debug Info builds.
CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO:STRING=
//Path to a program.
CMAKE_STRIP:FILEPATH=/Users/weishu/Library/Android/sdk/ndk-bundle/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64/bin/arm-linux-androideabi-strip
//The CMake toolchain file
CMAKE_TOOLCHAIN_FILE:FILEPATH=/Users/weishu/Library/Android/sdk/ndk-bundle/build/cmake/android.toolchain.cmake
//If this value is on, makefiles will be generated without the
// .SILENT directive, and all commands will be echoed to the console
// during the make. This is useful for debugging only. With Visual
// Studio IDE projects all commands are done without /nologo.
CMAKE_VERBOSE_MAKEFILE:BOOL=FALSE
//Value Computed by CMake
Project_BINARY_DIR:STATIC=/Users/weishu/dev/space/arthook/epic/library
//Value Computed by CMake
Project_SOURCE_DIR:STATIC=/Users/weishu/dev/space/arthook/epic/library
//Dependencies for the target
epic_LIB_DEPENDS:STATIC=general;/Users/weishu/Library/Android/sdk/ndk-bundle/platforms/android-9/arch-arm/usr/lib/liblog.so;
//Path to a library.
log-lib:FILEPATH=/Users/weishu/Library/Android/sdk/ndk-bundle/platforms/android-9/arch-arm/usr/lib/liblog.so
########################
# INTERNAL cache entries
########################
//ADVANCED property for variable: CMAKE_AR
CMAKE_AR-ADVANCED:INTERNAL=1
//This is the directory where this CMakeCache.txt was created
CMAKE_CACHEFILE_DIR:INTERNAL=/Users/weishu/dev/space/arthook/epic/library
//Major version of cmake used to create the current loaded cache
CMAKE_CACHE_MAJOR_VERSION:INTERNAL=3
//Minor version of cmake used to create the current loaded cache
CMAKE_CACHE_MINOR_VERSION:INTERNAL=9
//Patch version of cmake used to create the current loaded cache
CMAKE_CACHE_PATCH_VERSION:INTERNAL=1
//ADVANCED property for variable: CMAKE_COLOR_MAKEFILE
CMAKE_COLOR_MAKEFILE-ADVANCED:INTERNAL=1
//Path to CMake executable.
CMAKE_COMMAND:INTERNAL=/usr/local/Cellar/cmake/3.9.1/bin/cmake
//Path to cpack program executable.
CMAKE_CPACK_COMMAND:INTERNAL=/usr/local/Cellar/cmake/3.9.1/bin/cpack
//Path to ctest program executable.
CMAKE_CTEST_COMMAND:INTERNAL=/usr/local/Cellar/cmake/3.9.1/bin/ctest
//ADVANCED property for variable: CMAKE_CXX_COMPILER_AR
CMAKE_CXX_COMPILER_AR-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_CXX_COMPILER_RANLIB
CMAKE_CXX_COMPILER_RANLIB-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_CXX_FLAGS
CMAKE_CXX_FLAGS-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_CXX_FLAGS_DEBUG
CMAKE_CXX_FLAGS_DEBUG-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_CXX_FLAGS_MINSIZEREL
CMAKE_CXX_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_CXX_FLAGS_RELEASE
CMAKE_CXX_FLAGS_RELEASE-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_CXX_FLAGS_RELWITHDEBINFO
CMAKE_CXX_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_CXX_STANDARD_LIBRARIES
CMAKE_CXX_STANDARD_LIBRARIES-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_C_COMPILER_AR
CMAKE_C_COMPILER_AR-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_C_COMPILER_RANLIB
CMAKE_C_COMPILER_RANLIB-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_C_FLAGS
CMAKE_C_FLAGS-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_C_FLAGS_DEBUG
CMAKE_C_FLAGS_DEBUG-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_C_FLAGS_MINSIZEREL
CMAKE_C_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_C_FLAGS_RELEASE
CMAKE_C_FLAGS_RELEASE-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_C_FLAGS_RELWITHDEBINFO
CMAKE_C_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_C_STANDARD_LIBRARIES
CMAKE_C_STANDARD_LIBRARIES-ADVANCED:INTERNAL=1
//Path to cache edit program executable.
CMAKE_EDIT_COMMAND:INTERNAL=/usr/local/Cellar/cmake/3.9.1/bin/ccmake
//Executable file format
CMAKE_EXECUTABLE_FORMAT:INTERNAL=ELF
//ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS
CMAKE_EXE_LINKER_FLAGS-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS_DEBUG
CMAKE_EXE_LINKER_FLAGS_DEBUG-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS_MINSIZEREL
CMAKE_EXE_LINKER_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS_RELEASE
CMAKE_EXE_LINKER_FLAGS_RELEASE-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO
CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_EXPORT_COMPILE_COMMANDS
CMAKE_EXPORT_COMPILE_COMMANDS-ADVANCED:INTERNAL=1
//Name of external makefile project generator.
CMAKE_EXTRA_GENERATOR:INTERNAL=
//Name of generator.
CMAKE_GENERATOR:INTERNAL=Unix Makefiles
//Name of generator platform.
CMAKE_GENERATOR_PLATFORM:INTERNAL=
//Name of generator toolset.
CMAKE_GENERATOR_TOOLSET:INTERNAL=
//Source directory with the top level CMakeLists.txt file for this
// project
CMAKE_HOME_DIRECTORY:INTERNAL=/Users/weishu/dev/space/arthook/epic/library
//Install .so files without execute permission.
CMAKE_INSTALL_SO_NO_EXE:INTERNAL=0
//ADVANCED property for variable: CMAKE_LINKER
CMAKE_LINKER-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_MAKE_PROGRAM
CMAKE_MAKE_PROGRAM-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS
CMAKE_MODULE_LINKER_FLAGS-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS_DEBUG
CMAKE_MODULE_LINKER_FLAGS_DEBUG-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL
CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS_RELEASE
CMAKE_MODULE_LINKER_FLAGS_RELEASE-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO
CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_NM
CMAKE_NM-ADVANCED:INTERNAL=1
//number of local generators
CMAKE_NUMBER_OF_MAKEFILES:INTERNAL=1
//ADVANCED property for variable: CMAKE_OBJCOPY
CMAKE_OBJCOPY-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_OBJDUMP
CMAKE_OBJDUMP-ADVANCED:INTERNAL=1
//Platform information initialized
CMAKE_PLATFORM_INFO_INITIALIZED:INTERNAL=1
//ADVANCED property for variable: CMAKE_RANLIB
CMAKE_RANLIB-ADVANCED:INTERNAL=1
//Path to CMake installation.
CMAKE_ROOT:INTERNAL=/usr/local/Cellar/cmake/3.9.1/share/cmake
//ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS
CMAKE_SHARED_LINKER_FLAGS-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS_DEBUG
CMAKE_SHARED_LINKER_FLAGS_DEBUG-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL
CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS_RELEASE
CMAKE_SHARED_LINKER_FLAGS_RELEASE-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO
CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_SKIP_INSTALL_RPATH
CMAKE_SKIP_INSTALL_RPATH-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_SKIP_RPATH
CMAKE_SKIP_RPATH-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_STATIC_LINKER_FLAGS
CMAKE_STATIC_LINKER_FLAGS-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_STATIC_LINKER_FLAGS_DEBUG
CMAKE_STATIC_LINKER_FLAGS_DEBUG-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_STATIC_LINKER_FLAGS_MINSIZEREL
CMAKE_STATIC_LINKER_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_STATIC_LINKER_FLAGS_RELEASE
CMAKE_STATIC_LINKER_FLAGS_RELEASE-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO
CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_STRIP
CMAKE_STRIP-ADVANCED:INTERNAL=1
//uname command
CMAKE_UNAME:INTERNAL=/usr/bin/uname
//ADVANCED property for variable: CMAKE_VERBOSE_MAKEFILE
CMAKE_VERBOSE_MAKEFILE-ADVANCED:INTERNAL=1
================================================
FILE: library/build.gradle
================================================
apply plugin: 'com.android.library'
android {
compileSdkVersion 31
defaultConfig {
minSdkVersion 21
targetSdkVersion 31
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
ndk {
// Specifies the ABI configurations of your native
// libraries Gradle should build and package with your APK.
abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'
}
externalNativeBuild {
cmake {
cppFlags "-std=c++11"
// arguments "-DANDROID_TOOLCHAIN=gcc"
}
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
externalNativeBuild {
cmake {
path 'src/main/cpp/CMakeLists.txt'
}
}
lintOptions {
abortOnError false
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation "com.github.tiann:FreeReflection:3.1.0"
api 'me.weishu.exposed:exposed-xposedapi:0.4.5'
}
apply plugin: 'com.github.panpf.bintray-publish'
publish {
userOrg = 'twsxtd'//
groupId = 'me.weishu'
artifactId = 'epic'
publishVersion = '0.11.1'
desc = 'Android Java AOP Method Hook (Dexposed on ART)'
website = 'https://github.com/tiann/epic'
}
================================================
FILE: library/proguard-rules.pro
================================================
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in /Users/weishu/Library/Android/sdk/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# Add any project specific keep options here:
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
-keepattributes Signature,SourceFile,LineNumberTable,Exceptions
-keep class com.taobao.android.dexposed.** {*;}
-keep class me.weishu.epic.art.** {*;}
# delete log in release mode.
-assumenosideeffects class com.taobao.android.dexposed.utility.Logger {
public static void i(...);
public static void w(...);
public static void d(...);
public static void e(...);
}
-assumenosideeffects class com.taobao.android.dexposed.utility.Debug {
public static *** hexdump(...);
}
================================================
FILE: library/src/main/AndroidManifest.xml
================================================
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="me.weishu.epic">
<uses-sdk tools:overrideLibrary="de.robv.android.xposed" />
<application android:label="@string/app_name"
android:supportsRtl="true">
</application>
</manifest>
================================================
FILE: library/src/main/cpp/.gitignore
================================================
build/
================================================
FILE: library/src/main/cpp/CMakeLists.txt
================================================
# For more information about using CMake with Android Studio, read the
# documentation: https://d.android.com/studio/projects/add-native-code.html
# Sets the minimum version of CMake required to build the native library.
cmake_minimum_required(VERSION 3.4.1)
# Creates and names a library, sets it as either STATIC
# or SHARED, and provides the relative paths to its source code.
# You can define multiple libraries, and CMake builds them for you.
# Gradle automatically packages shared libraries with your APK.
set (SRC_LIST epic.cpp fake_dlfcn.cpp art.cpp)
add_library( # Sets the name of the library.
epic
# Sets the library as a shared library.
SHARED
# Provides a relative path to your source file(s).
${SRC_LIST})
# Searches for a specified prebuilt library and stores the path as a
# variable. Because CMake includes system libraries in the search path by
# default, you only need to specify the name of the public NDK library
# you want to add. CMake verifies that the library exists before
# completing its build.
find_library( # Sets the name of the path variable.
log-lib
# Specifies the name of the NDK library that
# you want CMake to locate.
log )
# Specifies libraries CMake should link to your target library. You
# can link multiple libraries, such as libraries you define in this
# build script, prebuilt third-party libraries, or system libraries.
target_link_libraries( # Specifies the target library.
epic
# Links the target library to the log library
# included in the NDK.
${log-lib} )
================================================
FILE: library/src/main/cpp/art.cpp
================================================
/*
* Copyright (c) 2017, weishu
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "art.h"
#include <android/log.h>
#include <cstddef>
#define LOGV(...) ((void)__android_log_print(ANDROID_LOG_INFO, "epic.Native", __VA_ARGS__))
#define ANDROID_R_API 30
#define MAX_SEARCH_LEN 2000
void* ArtHelper::runtime_instance_ = nullptr;
int ArtHelper::api = 0;
template <typename T>
inline int find_offset(void* hay, int size, T needle)
{
for (int i = 0; i < size; i += sizeof(T)) {
auto current = reinterpret_cast<T*>(reinterpret_cast<char*>(hay) + i);
if (*current == needle) {
return i;
}
}
return -1;
}
void ArtHelper::init(JNIEnv* env, int api)
{
ArtHelper::api = api;
JavaVM* javaVM;
env->GetJavaVM(&javaVM);
JavaVMExt* javaVMExt = (JavaVMExt*)javaVM;
void* runtime = javaVMExt->runtime;
if (runtime == nullptr) {
return;
}
if (api < ANDROID_R_API) {
runtime_instance_ = runtime;
} else {
int vm_offset = find_offset(runtime, MAX_SEARCH_LEN, javaVM);
runtime_instance_ = reinterpret_cast<void*>(reinterpret_cast<char*>(runtime) + vm_offset - offsetof(PartialRuntimeR, java_vm_));
}
}
void* ArtHelper::getClassLinker()
{
if (runtime_instance_ == nullptr || api < ANDROID_R_API) {
return nullptr;
}
PartialRuntimeR* runtimeR = (PartialRuntimeR*)runtime_instance_;
return runtimeR->class_linker_;
}
void* ArtHelper::getJniIdManager()
{
if (runtime_instance_ == nullptr || api < ANDROID_R_API) {
return nullptr;
}
PartialRuntimeR* runtimeR = (PartialRuntimeR*)runtime_instance_;
return runtimeR->jni_id_manager_;
}
void* ArtHelper::getJitCodeCache()
{
if (runtime_instance_ == nullptr || api < ANDROID_R_API) {
return nullptr;
}
PartialRuntimeR* runtimeR = (PartialRuntimeR*)runtime_instance_;
return runtimeR->jit_code_cache_;
}
void* ArtHelper::getHeap()
{
if (runtime_instance_ == nullptr) {
return nullptr;
}
if (api < 26) {
Runtime_7X* runtime7X = (Runtime_7X*)runtime_instance_;
return runtime7X->heap_;
} else if (api < ANDROID_R_API) {
Runtime_8X* runtime8X = (Runtime_8X*)runtime_instance_;
LOGV("bootclasspath : %s", runtime8X->boot_class_path_string_.c_str());
return runtime8X->heap_;
} else {
PartialRuntimeR* runtimeR = (PartialRuntimeR*)runtime_instance_;
return runtimeR->heap_;
}
}
================================================
FILE: library/src/main/cpp/art.h
================================================
/*
* Copyright (c) 2017, weishu
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef EPIC_ART_H
#define EPIC_ART_H
#include <jni.h>
#include <list>
#include <stdint.h>
#include <string>
#include <vector>
// Android 6.0: http://androidxref.com/6.0.0_r5/xref/art/runtime/runtime.h
// Android 7.0: http://androidxref.com/7.0.0_r1/xref/art/runtime/runtime.h
// Android 7.1.1: http://androidxref.com/7.1.1_r6/xref/art/runtime/runtime.h
// Android 8.0: http://androidxref.com/8.0.0_r4/xref/art/runtime/runtime.h
struct Runtime_7X {
uint64_t callee_save_methods_[3];
void* pre_allocated_OutOfMemoryError_;
void* pre_allocated_NoClassDefFoundError_;
void* resolution_method_;
void* imt_conflict_method_;
// Unresolved method has the same behavior as the conflict method, it is used by the class linker
// for differentiating between unfilled imt slots vs conflict slots in superclasses.
void* imt_unimplemented_method_;
void* sentinel_;
int instruction_set_;
uint32_t callee_save_method_frame_infos_[9]; // QuickMethodFrameInfo = uint32_t * 3
void* compiler_callbacks_;
bool is_zygote_;
bool must_relocate_;
bool is_concurrent_gc_enabled_;
bool is_explicit_gc_disabled_;
bool dex2oat_enabled_;
bool image_dex2oat_enabled_;
std::string compiler_executable_;
std::string patchoat_executable_;
std::vector<std::string> compiler_options_;
std::vector<std::string> image_compiler_options_;
std::string image_location_;
std::string boot_class_path_string_;
std::string class_path_string_;
std::vector<std::string> properties_;
// The default stack size for managed threads created by the runtime.
size_t default_stack_size_;
void* heap_;
};
struct Runtime_8X {
uint64_t callee_save_methods_[3];
void* pre_allocated_OutOfMemoryError_;
void* pre_allocated_NoClassDefFoundError_;
void* resolution_method_;
void* imt_conflict_method_;
// Unresolved method has the same behavior as the conflict method, it is used by the class linker
// for differentiating between unfilled imt slots vs conflict slots in superclasses.
void* imt_unimplemented_method_;
void* sentinel_;
int instruction_set_;
uint32_t callee_save_method_frame_infos_[9]; // QuickMethodFrameInfo = uint32_t * 3
void* compiler_callbacks_;
bool is_zygote_;
bool must_relocate_;
bool is_concurrent_gc_enabled_;
bool is_explicit_gc_disabled_;
bool dex2oat_enabled_;
bool image_dex2oat_enabled_;
std::string compiler_executable_;
std::string patchoat_executable_;
std::vector<std::string> compiler_options_;
std::vector<std::string> image_compiler_options_;
std::string image_location_;
std::string boot_class_path_string_;
std::string class_path_string_;
std::vector<std::string> properties_;
std::list<void*> agents_;
std::vector<void*> plugins_;
// The default stack size for managed threads created by the runtime.
size_t default_stack_size_;
void* heap_;
};
struct PartialRuntimeR {
void* heap_;
void* jit_arena_pool_;
void* arena_pool_;
// Special low 4gb pool for compiler linear alloc. We need ArtFields to be in low 4gb if we are
// compiling using a 32 bit image on a 64 bit compiler in case we resolve things in the image
// since the field arrays are int arrays in this case.
void* low_4gb_arena_pool_;
// Shared linear alloc for now.
void* linear_alloc_;
// The number of spins that are done before thread suspension is used to forcibly inflate.
size_t max_spins_before_thin_lock_inflation_;
void* monitor_list_;
void* monitor_pool_;
void* thread_list_;
void* intern_table_;
void* class_linker_;
void* signal_catcher_;
void* jni_id_manager_;
void* java_vm_;
void* jit_;
void* jit_code_cache_;
};
struct JavaVMExt {
void* functions;
void* runtime;
};
class ArtHelper {
public:
static void init(JNIEnv*, int);
static void* getRuntimeInstance() { return runtime_instance_; }
static void* getClassLinker();
static void* getJniIdManager();
static void* getJitCodeCache();
static void* getHeap();
private:
static void* runtime_instance_;
static int api;
};
#endif //EPIC_ART_H
================================================
FILE: library/src/main/cpp/build_with_cmake
================================================
#! /bin/sh
cmake -DCMAKE_TOOLCHAIN_FILE=$ANDROID_SDK/ndk-bundle/build/cmake/android.toolchain.cmake -DANDROID_TOOLCHAIN=gcc -H. -Bbuild && cd build && make
================================================
FILE: library/src/main/cpp/epic.cpp
================================================
/*
* Original Copyright 2014-2015 Marvin Wißfeld
* Modified work Copyright (c) 2017, weishu
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <jni.h>
#include <android/log.h>
#include <sys/mman.h>
#include <errno.h>
#include <unistd.h>
#include <dlfcn.h>
#include <cstdlib>
#include <sys/system_properties.h>
#include <fcntl.h>
#include "fake_dlfcn.h"
#include "art.h"
#undef NDEBUG
#ifdef NDEBUG
#define LOGV(...) ((void)__android_log_print(ANDROID_LOG_INFO, "epic.Native", __VA_ARGS__))
#else
#define LOGV(...)
#endif
#define JNIHOOK_CLASS "me/weishu/epic/art/EpicNative"
jobject (*addWeakGloablReference)(JavaVM *, void *, void *) = nullptr;
void* (*jit_load_)(bool*) = nullptr;
void* jit_compiler_handle_ = nullptr;
bool (*jit_compile_method_)(void*, void*, void*, bool) = nullptr;
void* (*JitCodeCache_GetCurrentRegion)(void*) = nullptr;
typedef bool (*JIT_COMPILE_METHOD1)(void *, void *, void *, bool);
typedef bool (*JIT_COMPILE_METHOD2)(void *, void *, void *, bool, bool); // Android Q
typedef bool (*JIT_COMPILE_METHOD3)(void *, void *, void *, void *, bool, bool); // Android R
typedef bool (*JIT_COMPILE_METHOD4)(void *, void *, void *, void *, int); // Android S
void (*jit_unload_)(void*) = nullptr;
class ScopedSuspendAll {};
void (*suspendAll)(ScopedSuspendAll*, char*) = nullptr;
void (*resumeAll)(ScopedSuspendAll*) = nullptr;
class ScopedJitSuspend {};
void (*startJit)(ScopedJitSuspend*) = nullptr;
void (*stopJit)(ScopedJitSuspend*) = nullptr;
void (*DisableMovingGc)(void*) = nullptr;
void* (*JniIdManager_DecodeMethodId_)(void*, jlong) = nullptr;
void* (*ClassLinker_MakeInitializedClassesVisiblyInitialized_)(void*, void*, bool) = nullptr;
void* __self() {
#ifdef __arm__
register uint32_t r9 asm("r9");
return (void*) r9;
#elif defined(__aarch64__)
register uint64_t x19 asm("x19");
return (void*) x19;
#else
#endif
};
static int api_level;
void init_entries(JNIEnv *env) {
char api_level_str[5];
__system_property_get("ro.build.version.sdk", api_level_str);
api_level = atoi(api_level_str);
LOGV("api level: %d", api_level);
ArtHelper::init(env, api_level);
if (api_level < 23) {
// Android L, art::JavaVMExt::AddWeakGlobalReference(art::Thread*, art::mirror::Object*)
void *handle = dlopen("libart.so", RTLD_LAZY | RTLD_GLOBAL);
addWeakGloablReference = (jobject (*)(JavaVM *, void *, void *)) dlsym(handle,
"_ZN3art9JavaVMExt22AddWeakGlobalReferenceEPNS_6ThreadEPNS_6mirror6ObjectE");
} else if (api_level < 24) {
// Android M, art::JavaVMExt::AddWeakGlobalRef(art::Thread*, art::mirror::Object*)
void *handle = dlopen("libart.so", RTLD_LAZY | RTLD_GLOBAL);
addWeakGloablReference = (jobject (*)(JavaVM *, void *, void *)) dlsym(handle,
"_ZN3art9JavaVMExt16AddWeakGlobalRefEPNS_6ThreadEPNS_6mirror6ObjectE");
} else {
// Android N and O, Google disallow us use dlsym;
void *handle = dlopen_ex("libart.so", RTLD_NOW);
void *jit_lib = dlopen_ex("libart-compiler.so", RTLD_NOW);
LOGV("fake dlopen install: %p", handle);
const char *addWeakGloablReferenceSymbol = api_level <= 25
? "_ZN3art9JavaVMExt16AddWeakGlobalRefEPNS_6ThreadEPNS_6mirror6ObjectE"
: "_ZN3art9JavaVMExt16AddWeakGlobalRefEPNS_6ThreadENS_6ObjPtrINS_6mirror6ObjectEEE";
addWeakGloablReference = (jobject (*)(JavaVM *, void *, void *)) dlsym_ex(handle, addWeakGloablReferenceSymbol);
jit_compile_method_ = (bool (*)(void *, void *, void *, bool)) dlsym_ex(jit_lib, "jit_compile_method");
jit_load_ = reinterpret_cast<void* (*)(bool*)>(dlsym_ex(jit_lib, "jit_load"));
bool generate_debug_info = false;
jit_compiler_handle_ = (jit_load_)(&generate_debug_info);
LOGV("jit compile_method: %p", jit_compile_method_);
suspendAll = reinterpret_cast<void (*)(ScopedSuspendAll*, char*)>(dlsym_ex(handle, "_ZN3art16ScopedSuspendAllC1EPKcb"));
resumeAll = reinterpret_cast<void (*)(ScopedSuspendAll*)>(dlsym_ex(handle, "_ZN3art16ScopedSuspendAllD1Ev"));
if (api_level >= 30) {
// Android R would not directly return ArtMethod address but an internal id
ClassLinker_MakeInitializedClassesVisiblyInitialized_ = reinterpret_cast<void* (*)(void*, void*, bool)>(dlsym_ex(handle, "_ZN3art11ClassLinker40MakeInitializedClassesVisiblyInitializedEPNS_6ThreadEb"));
JniIdManager_DecodeMethodId_ = reinterpret_cast<void* (*)(void*, jlong)>(dlsym_ex(handle, "_ZN3art3jni12JniIdManager14DecodeMethodIdEP10_jmethodID"));
if (api_level >= 31) {
// Android S CompileMethod accepts a CompilationKind enum instead of two booleans
// source: https://android.googlesource.com/platform/art/+/refs/heads/android12-release/compiler/jit/jit_compiler.cc
jit_compile_method_ = (bool (*)(void *, void *, void *, bool)) dlsym_ex(jit_lib, "_ZN3art3jit11JitCompiler13CompileMethodEPNS_6ThreadEPNS0_15JitMemoryRegionEPNS_9ArtMethodENS_15CompilationKindE");
} else {
jit_compile_method_ = (bool (*)(void *, void *, void *, bool)) dlsym_ex(jit_lib, "_ZN3art3jit11JitCompiler13CompileMethodEPNS_6ThreadEPNS0_15JitMemoryRegionEPNS_9ArtMethodEbb");
}
JitCodeCache_GetCurrentRegion = (void* (*)(void*)) dlsym_ex(handle, "_ZN3art3jit12JitCodeCache16GetCurrentRegionEv");
}
// Disable this now.
// startJit = reinterpret_cast<void(*)(ScopedJitSuspend*)>(dlsym_ex(handle, "_ZN3art3jit16ScopedJitSuspendD1Ev"));
// stopJit = reinterpret_cast<void(*)(ScopedJitSuspend*)>(dlsym_ex(handle, "_ZN3art3jit16ScopedJitSuspendC1Ev"));
// DisableMovingGc = reinterpret_cast<void(*)(void*)>(dlsym_ex(handle, "_ZN3art2gc4Heap15DisableMovingGcEv"));
}
LOGV("addWeakGloablReference: %p", addWeakGloablReference);
}
jboolean epic_compile(JNIEnv *env, jclass, jobject method, jlong self) {
LOGV("self from native peer: %p, from register: %p", reinterpret_cast<void*>(self), __self());
jlong art_method = (jlong) env->FromReflectedMethod(method);
if (art_method % 2 == 1) {
art_method = reinterpret_cast<jlong>(JniIdManager_DecodeMethodId_(ArtHelper::getJniIdManager(), art_method));
}
bool ret;
if (api_level >= 30) {
void* current_region = JitCodeCache_GetCurrentRegion(ArtHelper::getJitCodeCache());
if (api_level >= 31) {
ret = ((JIT_COMPILE_METHOD4)jit_compile_method_)(jit_compiler_handle_, reinterpret_cast<void*>(self),
reinterpret_cast<void*>(current_region),
reinterpret_cast<void*>(art_method), 1);
} else {
ret = ((JIT_COMPILE_METHOD3)jit_compile_method_)(jit_compiler_handle_, reinterpret_cast<void*>(self),
reinterpret_cast<void*>(current_region),
reinterpret_cast<void*>(art_method), false, false);
}
} else if (api_level >= 29) {
ret = ((JIT_COMPILE_METHOD2) jit_compile_method_)(jit_compiler_handle_,
reinterpret_cast<void *>(art_method),
reinterpret_cast<void *>(self), false, false);
} else {
ret = ((JIT_COMPILE_METHOD1) jit_compile_method_)(jit_compiler_handle_,
reinterpret_cast<void *>(art_method),
reinterpret_cast<void *>(self), false);
}
return (jboolean)ret;
}
jlong epic_suspendAll(JNIEnv *, jclass) {
ScopedSuspendAll *scopedSuspendAll = (ScopedSuspendAll *) malloc(sizeof(ScopedSuspendAll));
suspendAll(scopedSuspendAll, "stop_jit");
return reinterpret_cast<jlong >(scopedSuspendAll);
}
void epic_resumeAll(JNIEnv* env, jclass, jlong obj) {
ScopedSuspendAll* scopedSuspendAll = reinterpret_cast<ScopedSuspendAll*>(obj);
resumeAll(scopedSuspendAll);
}
jlong epic_stopJit(JNIEnv*, jclass) {
ScopedJitSuspend *scopedJitSuspend = (ScopedJitSuspend *) malloc(sizeof(ScopedJitSuspend));
stopJit(scopedJitSuspend);
return reinterpret_cast<jlong >(scopedJitSuspend);
}
void epic_startJit(JNIEnv*, jclass, jlong obj) {
ScopedJitSuspend *scopedJitSuspend = reinterpret_cast<ScopedJitSuspend *>(obj);
startJit(scopedJitSuspend);
}
void epic_disableMovingGc(JNIEnv* env, jclass ,jint api) {
void *heap = ArtHelper::getHeap();
DisableMovingGc(heap);
}
jboolean epic_munprotect(JNIEnv *env, jclass, jlong addr, jlong len) {
long pagesize = sysconf(_SC_PAGESIZE);
unsigned alignment = (unsigned)((unsigned long long)addr % pagesize);
LOGV("munprotect page size: %d, alignment: %d", pagesize, alignment);
int i = mprotect((void *) (addr - alignment), (size_t) (alignment + len),
PROT_READ | PROT_WRITE | PROT_EXEC);
if (i == -1) {
LOGV("mprotect failed: %s (%d)", strerror(errno), errno);
return JNI_FALSE;
}
return JNI_TRUE;
}
jboolean epic_cacheflush(JNIEnv *env, jclass, jlong addr, jlong len) {
#if defined(__arm__)
int i = cacheflush(addr, addr + len, 0);
LOGV("arm cacheflush for, %ul", addr);
if (i == -1) {
LOGV("cache flush failed: %s (%d)", strerror(errno), errno);
return JNI_FALSE;
}
#elif defined(__aarch64__)
char* begin = reinterpret_cast<char*>(addr);
__builtin___clear_cache(begin, begin + len);
LOGV("aarch64 __builtin___clear_cache, %p", (void*)begin);
#endif
return JNI_TRUE;
}
void epic_MakeInitializedClassVisibilyInitialized(JNIEnv *env, jclass, jlong self) {
if (api_level >= 30 && ClassLinker_MakeInitializedClassesVisiblyInitialized_ && ArtHelper::getClassLinker()) {
ClassLinker_MakeInitializedClassesVisiblyInitialized_(ArtHelper::getClassLinker(), reinterpret_cast<void*>(self), true);
}
}
void epic_memcpy(JNIEnv *env, jclass, jlong src, jlong dest, jint length) {
char *srcPnt = (char *) src;
char *destPnt = (char *) dest;
for (int i = 0; i < length; ++i) {
destPnt[i] = srcPnt[i];
}
}
void epic_memput(JNIEnv *env, jclass, jbyteArray src, jlong dest) {
jbyte *srcPnt = env->GetByteArrayElements(src, 0);
jsize length = env->GetArrayLength(src);
unsigned char *destPnt = (unsigned char *) dest;
for (int i = 0; i < length; ++i) {
// LOGV("put %d with %d", i, *(srcPnt + i));
destPnt[i] = (unsigned char) srcPnt[i];
}
env->ReleaseByteArrayElements(src, srcPnt, 0);
}
jbyteArray epic_memget(JNIEnv *env, jclass, jlong src, jint length) {
jbyteArray dest = env->NewByteArray(length);
if (dest == NULL) {
return NULL;
}
unsigned char *destPnt = (unsigned char *) env->GetByteArrayElements(dest, 0);
unsigned char *srcPnt = (unsigned char *) src;
for (int i = 0; i < length; ++i) {
destPnt[i] = srcPnt[i];
}
env->ReleaseByteArrayElements(dest, (jbyte *) destPnt, 0);
return dest;
}
jlong epic_mmap(JNIEnv *env, jclass, jint length) {
void *space = mmap(0, (size_t) length, PROT_READ | PROT_WRITE | PROT_EXEC,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if (space == MAP_FAILED) {
LOGV("mmap failed: %d", errno);
return 0;
}
return (jlong) space;
}
void epic_munmap(JNIEnv *env, jclass, jlong addr, jint length) {
int r = munmap((void *) addr, (size_t) length);
if (r == -1) {
LOGV("munmap failed: %d", errno);
}
}
jlong epic_malloc(JNIEnv *env, jclass, jint size) {
size_t length = sizeof(void *) * size;
void *ptr = malloc(length);
LOGV("malloc :%d of memory at: %p", (int) length, ptr);
return (jlong) ptr;
}
jobject epic_getobject(JNIEnv *env, jclass clazz, jlong self, jlong address) {
JavaVM *vm;
env->GetJavaVM(&vm);
LOGV("java vm: %p, self: %p, address: %p", vm, (void*) self, (void*) address);
jobject object = addWeakGloablReference(vm, (void *) self, (void *) address);
jobject new_local_object = env->NewLocalRef(object);
env->DeleteWeakGlobalRef(object);
return new_local_object;
}
jlong epic_getMethodAddress(JNIEnv *env, jclass clazz, jobject method) {
jlong art_method = (jlong) env->FromReflectedMethod(method);
if (art_method % 2 == 1) {
art_method = reinterpret_cast<jlong>(JniIdManager_DecodeMethodId_(ArtHelper::getJniIdManager(), art_method));
}
return art_method;
}
jboolean epic_isGetObjectAvaliable(JNIEnv *, jclass) {
return (jboolean) (addWeakGloablReference != nullptr);
}
jboolean epic_activate(JNIEnv* env, jclass jclazz, jlong jumpToAddress, jlong pc, jlong sizeOfDirectJump,
jlong sizeOfBridgeJump, jbyteArray code) {
// fetch the array, we can not call this when thread suspend(may lead deadlock)
jbyte *srcPnt = env->GetByteArrayElements(code, 0);
jsize length = env->GetArrayLength(code);
jlong cookie = 0;
bool isNougat = api_level >= 24;
if (isNougat) {
// We do thus things:
// 1. modify the code mprotect
// 2. modify the code
// Ideal, this two operation must be atomic. Below N, this is safe, because no one
// modify the code except ourselves;
// But in Android N, When the jit is working, between our step 1 and step 2,
// if we modity the mprotect of the code, and planning to write the code,
// the jit thread may modify the mprotect of the code meanwhile
// we must suspend all thread to ensure the atomic operation.
LOGV("suspend all thread.");
cookie = epic_suspendAll(env, jclazz);
}
jboolean result = epic_munprotect(env, jclazz, jumpToAddress, sizeOfDirectJump);
if (result) {
unsigned char *destPnt = (unsigned char *) jumpToAddress;
for (int i = 0; i < length; ++i) {
destPnt[i] = (unsigned char) srcPnt[i];
}
jboolean ret = epic_cacheflush(env, jclazz, pc, sizeOfBridgeJump);
if (!ret) {
LOGV("cache flush failed!!");
}
} else {
LOGV("Writing hook failed: Unable to unprotect memory at %d", jumpToAddress);
}
if (cookie != 0) {
LOGV("resume all thread.");
epic_resumeAll(env, jclazz, cookie);
}
env->ReleaseByteArrayElements(code, srcPnt, 0);
return result;
}
static JNINativeMethod dexposedMethods[] = {
{"mmap", "(I)J", (void *) epic_mmap},
{"munmap", "(JI)Z", (void *) epic_munmap},
{"memcpy", "(JJI)V", (void *) epic_memcpy},
{"memput", "([BJ)V", (void *) epic_memput},
{"memget", "(JI)[B", (void *) epic_memget},
{"munprotect", "(JJ)Z", (void *) epic_munprotect},
{"getMethodAddress", "(Ljava/lang/reflect/Member;)J", (void *) epic_getMethodAddress},
{"cacheflush", "(JJ)Z", (void *) epic_cacheflush},
{"MakeInitializedClassVisibilyInitialized", "(J)V", (void *) epic_MakeInitializedClassVisibilyInitialized},
{"malloc", "(I)J", (void *) epic_malloc},
{"getObjectNative", "(JJ)Ljava/lang/Object;", (void *) epic_getobject},
{"compileMethod", "(Ljava/lang/reflect/Member;J)Z",(void *) epic_compile},
{"suspendAll", "()J", (void *) epic_suspendAll},
{"resumeAll", "(J)V", (void *) epic_resumeAll},
{"stopJit", "()J", (void *) epic_stopJit},
{"startJit", "(J)V", (void *) epic_startJit},
{"disableMovingGc", "(I)V", (void *) epic_disableMovingGc},
{"activateNative", "(JJJJ[B)Z", (void *) epic_activate},
{"isGetObjectAvailable", "()Z", (void *) epic_isGetObjectAvaliable}
};
static int registerNativeMethods(JNIEnv *env, const char *className,
JNINativeMethod *gMethods, int numMethods) {
jclass clazz = env->FindClass(className);
if (clazz == NULL) {
return JNI_FALSE;
}
if (env->RegisterNatives(clazz, gMethods, numMethods) < 0) {
return JNI_FALSE;
}
return JNI_TRUE;
}
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
JNIEnv *env = NULL;
LOGV("JNI_OnLoad");
if (vm->GetEnv((void **) &env, JNI_VERSION_1_6) != JNI_OK) {
return -1;
}
if (!registerNativeMethods(env, JNIHOOK_CLASS, dexposedMethods,
sizeof(dexposedMethods) / sizeof(dexposedMethods[0]))) {
return -1;
}
init_entries(env);
return JNI_VERSION_1_6;
}
================================================
FILE: library/src/main/cpp/fake_dlfcn.cpp
================================================
// Copyright (c) 2016 avs333
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//fork from https://github.com/avs333/Nougat_dlfunctions
//do some modify
//support all cpu abi such as x86, x86_64
//support filename search if filename is not start with '/'
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <elf.h>
#include <dlfcn.h>
#include <sys/system_properties.h>
#include <android/log.h>
#define TAG_NAME "dlfcn_ex"
#ifdef LOG_DBG
#define log_info(fmt, args...) __android_log_print(ANDROID_LOG_INFO, TAG_NAME, (const char *) fmt, ##args)
#define log_err(fmt, args...) __android_log_print(ANDROID_LOG_ERROR, TAG_NAME, (const char *) fmt, ##args)
#define log_dbg log_info
#else
#define log_dbg(...)
#define log_info(fmt, args...)
#define log_err(fmt, args...)
#endif
#ifdef __LP64__
#define Elf_Ehdr Elf64_Ehdr
#define Elf_Shdr Elf64_Shdr
#define Elf_Sym Elf64_Sym
#else
#define Elf_Ehdr Elf32_Ehdr
#define Elf_Shdr Elf32_Shdr
#define Elf_Sym Elf32_Sym
#endif
struct ctx {
void *load_addr;
void *dynstr;
void *dynsym;
int nsyms;
off_t bias;
};
extern "C" {
static int fake_dlclose(void *handle) {
if (handle) {
struct ctx *ctx = (struct ctx *) handle;
if (ctx->dynsym) free(ctx->dynsym); /* we're saving dynsym and dynstr */
if (ctx->dynstr) free(ctx->dynstr); /* from library file just in case */
free(ctx);
}
return 0;
}
/* flags are ignored */
static void *fake_dlopen_with_path(const char *libpath, int flags) {
FILE *maps;
char buff[256];
struct ctx *ctx = 0;
off_t load_addr, size;
int k, fd = -1, found = 0;
char *shoff;
Elf_Ehdr *elf = (Elf_Ehdr *) MAP_FAILED;
#define fatal(fmt, args...) do { log_err(fmt,##args); goto err_exit; } while(0)
maps = fopen("/proc/self/maps", "r");
if (!maps) fatal("failed to open maps");
while (!found && fgets(buff, sizeof(buff), maps)) {
if (strstr(buff, libpath) && (strstr(buff, "r-xp") || strstr(buff, "r--p"))) found = 1;
}
fclose(maps);
if (!found) fatal("%s not found in my userspace", libpath);
if (sscanf(buff, "%lx", &load_addr) != 1)
fatal("failed to read load address for %s", libpath);
log_info("%s loaded in Android at 0x%08lx", libpath, load_addr);
/* Now, mmap the same library once again */
fd = open(libpath, O_RDONLY);
if (fd < 0) fatal("failed to open %s", libpath);
size = lseek(fd, 0, SEEK_END);
if (size <= 0) fatal("lseek() failed for %s", libpath);
elf = (Elf_Ehdr *) mmap(0, size, PROT_READ, MAP_SHARED, fd, 0);
close(fd);
fd = -1;
if (elf == MAP_FAILED) fatal("mmap() failed for %s", libpath);
ctx = (struct ctx *) calloc(1, sizeof(struct ctx));
if (!ctx) fatal("no memory for %s", libpath);
ctx->load_addr = (void *) load_addr;
shoff = ((char *) elf) + elf->e_shoff;
for (k = 0; k < elf->e_shnum; k++, shoff += elf->e_shentsize) {
Elf_Shdr *sh = (Elf_Shdr *) shoff;
log_dbg("%s: k=%d shdr=%p type=%x", __func__, k, sh, sh->sh_type);
switch (sh->sh_type) {
case SHT_DYNSYM:
if (ctx->dynsym) fatal("%s: duplicate DYNSYM sections", libpath); /* .dynsym */
ctx->dynsym = malloc(sh->sh_size);
if (!ctx->dynsym) fatal("%s: no memory for .dynsym", libpath);
memcpy(ctx->dynsym, ((char *) elf) + sh->sh_offset, sh->sh_size);
ctx->nsyms = (sh->sh_size / sizeof(Elf_Sym));
break;
case SHT_STRTAB:
if (ctx->dynstr) break; /* .dynstr is guaranteed to be the first STRTAB */
ctx->dynstr = malloc(sh->sh_size);
if (!ctx->dynstr) fatal("%s: no memory for .dynstr", libpath);
memcpy(ctx->dynstr, ((char *) elf) + sh->sh_offset, sh->sh_size);
break;
case SHT_PROGBITS:
if (!ctx->dynstr || !ctx->dynsym) break;
/* won't even bother checking against the section name */
ctx->bias = (off_t) sh->sh_addr - (off_t) sh->sh_offset;
k = elf->e_shnum; /* exit for */
break;
}
}
munmap(elf, size);
elf = 0;
if (!ctx->dynstr || !ctx->dynsym) fatal("dynamic sections not found in %s", libpath);
#undef fatal
log_dbg("%s: ok, dynsym = %p, dynstr = %p", libpath, ctx->dynsym, ctx->dynstr);
return ctx;
err_exit:
if (fd >= 0) close(fd);
if (elf != MAP_FAILED) munmap(elf, size);
fake_dlclose(ctx);
return 0;
}
#if defined(__LP64__)
static const char *const kSystemLibDir = "/system/lib64/";
static const char *const kOdmLibDir = "/odm/lib64/";
static const char *const kVendorLibDir = "/vendor/lib64/";
static const char *const kApexLibDir = "/apex/com.android.runtime/lib64/";
static const char *const kApexArtNsLibDir = "/apex/com.android.art/lib64/";
#else
static const char *const kSystemLibDir = "/system/lib/";
static const char *const kOdmLibDir = "/odm/lib/";
static const char *const kVendorLibDir = "/vendor/lib/";
static const char *const kApexLibDir = "/apex/com.android.runtime/lib/";
static const char *const kApexArtNsLibDir = "/apex/com.android.art/lib/";
#endif
static void *fake_dlopen(const char *filename, int flags) {
if (strlen(filename) > 0 && filename[0] == '/') {
return fake_dlopen_with_path(filename, flags);
} else {
char buf[512] = {0};
void *handle = NULL;
//sysmtem
strcpy(buf, kSystemLibDir);
strcat(buf, filename);
handle = fake_dlopen_with_path(buf, flags);
if (handle) {
return handle;
}
// apex in ns com.android.runtime
memset(buf, 0, sizeof(buf));
strcpy(buf, kApexLibDir);
strcat(buf, filename);
handle = fake_dlopen_with_path(buf, flags);
if (handle) {
return handle;
}
// apex in ns com.android.art
memset(buf, 0, sizeof(buf));
strcpy(buf, kApexArtNsLibDir);
strcat(buf, filename);
handle = fake_dlopen_with_path(buf, flags);
if (handle) {
return handle;
}
//odm
memset(buf, 0, sizeof(buf));
strcpy(buf, kOdmLibDir);
strcat(buf, filename);
handle = fake_dlopen_with_path(buf, flags);
if (handle) {
return handle;
}
//vendor
memset(buf, 0, sizeof(buf));
strcpy(buf, kVendorLibDir);
strcat(buf, filename);
handle = fake_dlopen_with_path(buf, flags);
if (handle) {
return handle;
}
return fake_dlopen_with_path(filename, flags);
}
}
static void *fake_dlsym(void *handle, const char *name) {
int k;
struct ctx *ctx = (struct ctx *) handle;
Elf_Sym *sym = (Elf_Sym *) ctx->dynsym;
char *strings = (char *) ctx->dynstr;
for (k = 0; k < ctx->nsyms; k++, sym++)
if (strcmp(strings + sym->st_name, name) == 0) {
/* NB: sym->st_value is an offset into the section for relocatables,
but a VMA for shared libs or exe files, so we have to subtract the bias */
void *ret = (char *) ctx->load_addr + sym->st_value - ctx->bias;
log_info("%s found at %p", name, ret);
return ret;
}
return 0;
}
static const char *fake_dlerror() {
return NULL;
}
// =============== implementation for compat ==========
static int SDK_INT = -1;
static int get_sdk_level() {
if (SDK_INT > 0) {
return SDK_INT;
}
char sdk[PROP_VALUE_MAX] = {0};;
__system_property_get("ro.build.version.sdk", sdk);
SDK_INT = atoi(sdk);
return SDK_INT;
}
int dlclose_ex(void *handle) {
if (get_sdk_level() >= 24) {
return fake_dlclose(handle);
} else {
return dlclose(handle);
}
}
void *dlopen_ex(const char *filename, int flags) {
log_info("dlopen: %s", filename);
if (get_sdk_level() >= 24) {
return fake_dlopen(filename, flags);
} else {
return dlopen(filename, flags);
}
}
void *dlsym_ex(void *handle, const char *symbol) {
if (get_sdk_level() >= 24) {
return fake_dlsym(handle, symbol);
} else {
return dlsym(handle, symbol);
}
}
const char *dlerror_ex() {
if (get_sdk_level() >= 24) {
return fake_dlerror();
} else {
return dlerror();
}
}
}
================================================
FILE: library/src/main/cpp/fake_dlfcn.h
================================================
// Copyright (c) 2016 avs333
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
#ifndef DEXPOSED_DLFCN_H
#define DEXPOSED_DLFCN_H
#include <cstdlib>
#include <string.h>
#include <unistd.h>
extern "C" {
void *dlopen_ex(const char *filename, int flags);
void *dlsym_ex(void *handle, const char *symbol);
int dlclose_ex(void *handle);
const char *dlerror_ex();
};
#endif //DEXPOSED_DLFCN_H
================================================
FILE: library/src/main/java/com/taobao/android/dexposed/ClassUtils.java
================================================
/*
* Original work Copyright (c) 2005-2008, The Android Open Source Project
* Modified work Copyright (c) 2013, rovo89 and Tungstwenty
* Modified work Copyright (c) 2015, Alibaba Mobile Infrastructure (Android) Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.taobao.android.dexposed;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
/**
* <p>Operates on classes without using reflection.</p>
*
* <p>This class handles invalid {@code null} inputs as best it can.
* Each method documents its behaviour in more detail.</p>
*
* <p>The notion of a {@code canonical name} includes the human
* readable name for the type, for example {@code int[]}. The
* non-canonical method variants work with the JVM names, such as
* {@code [I}. </p>
*
* @since 2.0
* @version $Id: ClassUtils.java 1199894 2011-11-09 17:53:59Z ggregory $
*/
public class ClassUtils {
/**
* <p>The package separator character: <code>'.' == {@value}</code>.</p>
*/
public static final char PACKAGE_SEPARATOR_CHAR = '.';
/**
* <p>The package separator String: {@code "."}.</p>
*/
public static final String PACKAGE_SEPARATOR = String.valueOf(PACKAGE_SEPARATOR_CHAR);
/**
* <p>The inner class separator character: <code>'$' == {@value}</code>.</p>
*/
public static final char INNER_CLASS_SEPARATOR_CHAR = '$';
/**
* <p>The inner class separator String: {@code "$"}.</p>
*/
public static final String INNER_CLASS_SEPARATOR = String.valueOf(INNER_CLASS_SEPARATOR_CHAR);
/**
* <p>Empty string.</p>
*/
public static final String STRING_EMPTY = "";
/**
* Maps primitive {@code Class}es to their corresponding wrapper {@code Class}.
*/
private static final Map<Class<?>, Class<?>> primitiveWrapperMap = new HashMap<Class<?>, Class<?>>();
static {
primitiveWrapperMap.put(Boolean.TYPE, Boolean.class);
primitiveWrapperMap.put(Byte.TYPE, Byte.class);
primitiveWrapperMap.put(Character.TYPE, Character.class);
primitiveWrapperMap.put(Short.TYPE, Short.class);
primitiveWrapperMap.put(Integer.TYPE, Integer.class);
primitiveWrapperMap.put(Long.TYPE, Long.class);
primitiveWrapperMap.put(Double.TYPE, Double.class);
primitiveWrapperMap.put(Float.TYPE, Float.class);
primitiveWrapperMap.put(Void.TYPE, Void.TYPE);
}
/**
* Maps wrapper {@code Class}es to their corresponding primitive types.
*/
private static final Map<Class<?>, Class<?>> wrapperPrimitiveMap = new HashMap<Class<?>, Class<?>>();
static {
for (Class<?> primitiveClass : primitiveWrapperMap.keySet()) {
Class<?> wrapperClass = primitiveWrapperMap.get(primitiveClass);
if (!primitiveClass.equals(wrapperClass)) {
wrapperPrimitiveMap.put(wrapperClass, primitiveClass);
}
}
}
/**
* Maps a primitive class name to its corresponding abbreviation used in array class names.
gitextract_6vz_tr23/ ├── .github/ │ ├── FUNDING.yml │ └── workflows/ │ └── android.yml ├── .gitignore ├── LICENSE ├── README.md ├── README_cn.md ├── app/ │ ├── .gitignore │ ├── build.gradle │ ├── proguard-rules.pro │ └── src/ │ ├── androidTest/ │ │ └── java/ │ │ └── me/ │ │ └── weishu/ │ │ └── epic/ │ │ └── ExampleInstrumentedTest.java │ ├── main/ │ │ ├── AndroidManifest.xml │ │ ├── java/ │ │ │ └── me/ │ │ │ └── weishu/ │ │ │ └── epic/ │ │ │ └── samples/ │ │ │ ├── MainActivity.java │ │ │ ├── MainApplication.java │ │ │ └── tests/ │ │ │ ├── CallingConventationTest.java │ │ │ ├── LogMethodHook.java │ │ │ ├── TestCase.java │ │ │ ├── TestManager.java │ │ │ ├── TestSuite.java │ │ │ ├── arguments/ │ │ │ │ ├── AbsArgStaticCase.java │ │ │ │ ├── ArgStatic0.java │ │ │ │ ├── ArgStatic4.java │ │ │ │ ├── ArgStatic44.java │ │ │ │ ├── ArgStatic444.java │ │ │ │ ├── ArgStatic4444.java │ │ │ │ ├── ArgStatic4448.java │ │ │ │ ├── ArgStatic448.java │ │ │ │ ├── ArgStatic4484.java │ │ │ │ ├── ArgStatic4488.java │ │ │ │ ├── ArgStatic48.java │ │ │ │ ├── ArgStatic484.java │ │ │ │ ├── ArgStatic4844.java │ │ │ │ ├── ArgStatic4848.java │ │ │ │ ├── ArgStatic488.java │ │ │ │ ├── ArgStatic4884.java │ │ │ │ ├── ArgStatic4888.java │ │ │ │ ├── ArgStatic8.java │ │ │ │ ├── ArgStatic84.java │ │ │ │ ├── ArgStatic844.java │ │ │ │ ├── ArgStatic8444.java │ │ │ │ ├── ArgStatic8448.java │ │ │ │ ├── ArgStatic848.java │ │ │ │ ├── ArgStatic8484.java │ │ │ │ ├── ArgStatic8488.java │ │ │ │ ├── ArgStatic88.java │ │ │ │ ├── ArgStatic884.java │ │ │ │ ├── ArgStatic8844.java │ │ │ │ ├── ArgStatic8848.java │ │ │ │ ├── ArgStatic888.java │ │ │ │ ├── ArgStatic8884.java │ │ │ │ ├── ArgStatic8888.java │ │ │ │ └── ArgumentTarget.java │ │ │ ├── custom/ │ │ │ │ ├── Case.java │ │ │ │ ├── Case1.java │ │ │ │ ├── Case10_Default_Constructor.java │ │ │ │ ├── Case11_SuspendAll.java │ │ │ │ ├── Case12_MultiCallback.java │ │ │ │ ├── Case13_FastNative.java │ │ │ │ ├── Case14_GC.java │ │ │ │ ├── Case15_StopJit.java │ │ │ │ ├── Case16_SameEntry.java │ │ │ │ ├── Case17_SameMethod.java │ │ │ │ ├── Case18_returnConst.java │ │ │ │ ├── Case2.java │ │ │ │ ├── Case3.java │ │ │ │ ├── Case4.java │ │ │ │ ├── Case5.java │ │ │ │ ├── Case6.java │ │ │ │ ├── Case7.java │ │ │ │ ├── Case8_Activity_onCreate.java │ │ │ │ ├── Case9_ThreadMonitor.java │ │ │ │ ├── CaseManager.java │ │ │ │ └── Target.java │ │ │ ├── invoketype/ │ │ │ │ ├── InvokeConstructor.java │ │ │ │ └── InvokeTypeTarget.java │ │ │ └── returntype/ │ │ │ ├── BooleanType.java │ │ │ ├── ByteType.java │ │ │ ├── CharType.java │ │ │ ├── CustomType.java │ │ │ ├── DoubleType.java │ │ │ ├── FloatType.java │ │ │ ├── IntType.java │ │ │ ├── LongType.java │ │ │ ├── ReturnTypeTarget.java │ │ │ ├── ShortType.java │ │ │ ├── StringArrayType.java │ │ │ ├── StringType.java │ │ │ └── VoidType.java │ │ └── res/ │ │ ├── layout/ │ │ │ ├── activity_main.xml │ │ │ ├── child_layout.xml │ │ │ └── parent_layout.xml │ │ └── values/ │ │ ├── colors.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test/ │ └── java/ │ └── me/ │ └── weishu/ │ └── epic/ │ └── ExampleUnitTest.java ├── build.gradle ├── gradle/ │ └── wrapper/ │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradle.properties ├── gradlew ├── gradlew.bat ├── library/ │ ├── .gitignore │ ├── CMakeCache.txt │ ├── build.gradle │ ├── proguard-rules.pro │ └── src/ │ └── main/ │ ├── AndroidManifest.xml │ ├── cpp/ │ │ ├── .gitignore │ │ ├── CMakeLists.txt │ │ ├── art.cpp │ │ ├── art.h │ │ ├── build_with_cmake │ │ ├── epic.cpp │ │ ├── fake_dlfcn.cpp │ │ └── fake_dlfcn.h │ ├── java/ │ │ ├── com/ │ │ │ └── taobao/ │ │ │ └── android/ │ │ │ └── dexposed/ │ │ │ ├── ClassUtils.java │ │ │ ├── DeviceCheck.java │ │ │ └── utility/ │ │ │ ├── Debug.java │ │ │ ├── Logger.java │ │ │ ├── NeverCalled.java │ │ │ ├── NougatPolicy.java │ │ │ ├── Platform.java │ │ │ ├── Runtime.java │ │ │ └── Unsafe.java │ │ ├── de/ │ │ │ └── robv/ │ │ │ └── android/ │ │ │ └── xposed/ │ │ │ └── DexposedBridge.java │ │ └── me/ │ │ └── weishu/ │ │ └── epic/ │ │ └── art/ │ │ ├── Epic.java │ │ ├── EpicNative.java │ │ ├── Trampoline.java │ │ ├── arch/ │ │ │ ├── Arm64.java │ │ │ ├── Arm64_2.java │ │ │ ├── ShellCode.java │ │ │ └── Thumb2.java │ │ ├── entry/ │ │ │ ├── Entry.java │ │ │ ├── Entry64.java │ │ │ └── Entry64_2.java │ │ └── method/ │ │ ├── ArtMethod.java │ │ └── Offset.java │ └── res/ │ └── values/ │ └── strings.xml └── settings.gradle
SYMBOL INDEX (732 symbols across 102 files)
FILE: app/src/main/java/me/weishu/epic/samples/MainActivity.java
class MainActivity (line 21) | public class MainActivity extends Activity {
method onCreate (line 29) | @Override
class MyAdapter (line 42) | private class MyAdapter extends BaseExpandableListAdapter {
method getGroupCount (line 44) | @Override
method getChildrenCount (line 49) | @Override
method getGroup (line 54) | @Override
method getChild (line 59) | @Override
method getGroupId (line 64) | @Override
method getChildId (line 69) | @Override
method hasStableIds (line 74) | @Override
method getGroupView (line 79) | @Override
method getChildView (line 94) | @Override
method isChildSelectable (line 124) | @Override
FILE: app/src/main/java/me/weishu/epic/samples/MainApplication.java
class MainApplication (line 9) | public class MainApplication extends Application {
method getAppContext (line 13) | public static Context getAppContext() {
method attachBaseContext (line 17) | @Override
FILE: app/src/main/java/me/weishu/epic/samples/tests/CallingConventationTest.java
class CallingConventationTest (line 8) | public class CallingConventationTest {
method longParams1 (line 10) | public static void longParams1() {
method longParams2 (line 19) | public static void longParams2() {
method longParams3 (line 27) | public static void longParams3() {
FILE: app/src/main/java/me/weishu/epic/samples/tests/LogMethodHook.java
class LogMethodHook (line 13) | public class LogMethodHook extends XC_MethodHook {
method beforeHookedMethod (line 15) | @Override
method afterHookedMethod (line 21) | @Override
method paramToString (line 27) | private static String paramToString(MethodHookParam param) {
FILE: app/src/main/java/me/weishu/epic/samples/tests/TestCase.java
class TestCase (line 11) | public abstract class TestCase {
method TestCase (line 16) | public TestCase(String name) {
method test (line 20) | public abstract void test();
method predicate (line 22) | public abstract boolean predicate();
method validate (line 24) | public boolean validate() {
method getName (line 38) | public String getName() {
FILE: app/src/main/java/me/weishu/epic/samples/tests/TestManager.java
class TestManager (line 72) | public class TestManager {
method TestManager (line 77) | private TestManager() {
method getInstance (line 81) | public static TestManager getInstance() {
method addSuite (line 85) | public void addSuite(TestSuite suite) {
method getAllSuites (line 89) | public List<TestSuite> getAllSuites() {
method initAllSuites (line 93) | private void initAllSuites() {
FILE: app/src/main/java/me/weishu/epic/samples/tests/TestSuite.java
class TestSuite (line 10) | public class TestSuite {
method TestSuite (line 14) | public TestSuite(String name) {
method addCase (line 18) | public void addCase(TestCase caze) {
method getName (line 22) | public String getName() {
method getAllCases (line 26) | public List<TestCase> getAllCases() {
FILE: app/src/main/java/me/weishu/epic/samples/tests/arguments/AbsArgStaticCase.java
class AbsArgStaticCase (line 19) | public abstract class AbsArgStaticCase extends TestCase {
method AbsArgStaticCase (line 27) | public AbsArgStaticCase() {
method test (line 37) | @Override
method predicate (line 54) | @Override
method getArguments (line 73) | private long[] getArguments() {
method getTargetMethod (line 82) | protected Method getTargetMethod() {
method getArgumentNumber (line 91) | protected int getArgumentNumber() {
method makeCall (line 95) | protected void makeCall(long... args) {
method nextLong (line 99) | private long nextLong() {
method getParamsSignature (line 104) | private Class<?>[] getParamsSignature() {
method toHex (line 122) | private String[] toHex(long[] value) {
FILE: app/src/main/java/me/weishu/epic/samples/tests/arguments/ArgStatic0.java
class ArgStatic0 (line 13) | public class ArgStatic0 extends TestCase {
method ArgStatic0 (line 17) | public ArgStatic0() {
method test (line 21) | @Override
method predicate (line 38) | @Override
FILE: app/src/main/java/me/weishu/epic/samples/tests/arguments/ArgStatic4.java
class ArgStatic4 (line 8) | public class ArgStatic4 extends AbsArgStaticCase {
method makeCall (line 10) | @Override
FILE: app/src/main/java/me/weishu/epic/samples/tests/arguments/ArgStatic44.java
class ArgStatic44 (line 8) | public class ArgStatic44 extends AbsArgStaticCase {
method makeCall (line 10) | @Override
FILE: app/src/main/java/me/weishu/epic/samples/tests/arguments/ArgStatic444.java
class ArgStatic444 (line 11) | public class ArgStatic444 extends AbsArgStaticCase {
method makeCall (line 13) | @Override
FILE: app/src/main/java/me/weishu/epic/samples/tests/arguments/ArgStatic4444.java
class ArgStatic4444 (line 7) | public class ArgStatic4444 extends AbsArgStaticCase {
method makeCall (line 8) | @Override
FILE: app/src/main/java/me/weishu/epic/samples/tests/arguments/ArgStatic4448.java
class ArgStatic4448 (line 7) | public class ArgStatic4448 extends AbsArgStaticCase {
method makeCall (line 8) | @Override
FILE: app/src/main/java/me/weishu/epic/samples/tests/arguments/ArgStatic448.java
class ArgStatic448 (line 7) | public class ArgStatic448 extends AbsArgStaticCase {
method makeCall (line 9) | @Override
FILE: app/src/main/java/me/weishu/epic/samples/tests/arguments/ArgStatic4484.java
class ArgStatic4484 (line 7) | public class ArgStatic4484 extends AbsArgStaticCase {
method makeCall (line 8) | @Override
FILE: app/src/main/java/me/weishu/epic/samples/tests/arguments/ArgStatic4488.java
class ArgStatic4488 (line 7) | public class ArgStatic4488 extends AbsArgStaticCase {
method makeCall (line 8) | @Override
FILE: app/src/main/java/me/weishu/epic/samples/tests/arguments/ArgStatic48.java
class ArgStatic48 (line 8) | public class ArgStatic48 extends AbsArgStaticCase {
method makeCall (line 10) | @Override
FILE: app/src/main/java/me/weishu/epic/samples/tests/arguments/ArgStatic484.java
class ArgStatic484 (line 7) | public class ArgStatic484 extends AbsArgStaticCase {
method makeCall (line 8) | @Override
FILE: app/src/main/java/me/weishu/epic/samples/tests/arguments/ArgStatic4844.java
class ArgStatic4844 (line 7) | public class ArgStatic4844 extends AbsArgStaticCase {
method makeCall (line 8) | @Override
FILE: app/src/main/java/me/weishu/epic/samples/tests/arguments/ArgStatic4848.java
class ArgStatic4848 (line 7) | public class ArgStatic4848 extends AbsArgStaticCase {
method makeCall (line 8) | @Override
FILE: app/src/main/java/me/weishu/epic/samples/tests/arguments/ArgStatic488.java
class ArgStatic488 (line 7) | public class ArgStatic488 extends AbsArgStaticCase {
method makeCall (line 8) | @Override
FILE: app/src/main/java/me/weishu/epic/samples/tests/arguments/ArgStatic4884.java
class ArgStatic4884 (line 7) | public class ArgStatic4884 extends AbsArgStaticCase {
method makeCall (line 8) | @Override
FILE: app/src/main/java/me/weishu/epic/samples/tests/arguments/ArgStatic4888.java
class ArgStatic4888 (line 7) | public class ArgStatic4888 extends AbsArgStaticCase {
method makeCall (line 8) | @Override
FILE: app/src/main/java/me/weishu/epic/samples/tests/arguments/ArgStatic8.java
class ArgStatic8 (line 8) | public class ArgStatic8 extends AbsArgStaticCase {
method makeCall (line 10) | @Override
FILE: app/src/main/java/me/weishu/epic/samples/tests/arguments/ArgStatic84.java
class ArgStatic84 (line 8) | public class ArgStatic84 extends AbsArgStaticCase {
method makeCall (line 10) | @Override
FILE: app/src/main/java/me/weishu/epic/samples/tests/arguments/ArgStatic844.java
class ArgStatic844 (line 7) | public class ArgStatic844 extends AbsArgStaticCase {
method makeCall (line 8) | @Override
FILE: app/src/main/java/me/weishu/epic/samples/tests/arguments/ArgStatic8444.java
class ArgStatic8444 (line 7) | public class ArgStatic8444 extends AbsArgStaticCase {
method makeCall (line 8) | @Override
FILE: app/src/main/java/me/weishu/epic/samples/tests/arguments/ArgStatic8448.java
class ArgStatic8448 (line 7) | public class ArgStatic8448 extends AbsArgStaticCase {
method makeCall (line 8) | @Override
FILE: app/src/main/java/me/weishu/epic/samples/tests/arguments/ArgStatic848.java
class ArgStatic848 (line 7) | public class ArgStatic848 extends AbsArgStaticCase {
method makeCall (line 8) | @Override
FILE: app/src/main/java/me/weishu/epic/samples/tests/arguments/ArgStatic8484.java
class ArgStatic8484 (line 7) | public class ArgStatic8484 extends AbsArgStaticCase {
method makeCall (line 8) | @Override
FILE: app/src/main/java/me/weishu/epic/samples/tests/arguments/ArgStatic8488.java
class ArgStatic8488 (line 7) | public class ArgStatic8488 extends AbsArgStaticCase {
method makeCall (line 8) | @Override
FILE: app/src/main/java/me/weishu/epic/samples/tests/arguments/ArgStatic88.java
class ArgStatic88 (line 8) | public class ArgStatic88 extends AbsArgStaticCase {
method makeCall (line 10) | @Override
FILE: app/src/main/java/me/weishu/epic/samples/tests/arguments/ArgStatic884.java
class ArgStatic884 (line 7) | public class ArgStatic884 extends AbsArgStaticCase {
method makeCall (line 8) | @Override
FILE: app/src/main/java/me/weishu/epic/samples/tests/arguments/ArgStatic8844.java
class ArgStatic8844 (line 7) | public class ArgStatic8844 extends AbsArgStaticCase {
method makeCall (line 8) | @Override
FILE: app/src/main/java/me/weishu/epic/samples/tests/arguments/ArgStatic8848.java
class ArgStatic8848 (line 7) | public class ArgStatic8848 extends AbsArgStaticCase {
method makeCall (line 8) | @Override
FILE: app/src/main/java/me/weishu/epic/samples/tests/arguments/ArgStatic888.java
class ArgStatic888 (line 7) | public class ArgStatic888 extends AbsArgStaticCase {
method makeCall (line 8) | @Override
FILE: app/src/main/java/me/weishu/epic/samples/tests/arguments/ArgStatic8884.java
class ArgStatic8884 (line 7) | public class ArgStatic8884 extends AbsArgStaticCase {
method makeCall (line 8) | @Override
FILE: app/src/main/java/me/weishu/epic/samples/tests/arguments/ArgStatic8888.java
class ArgStatic8888 (line 7) | public class ArgStatic8888 extends AbsArgStaticCase {
method makeCall (line 8) | @Override
FILE: app/src/main/java/me/weishu/epic/samples/tests/arguments/ArgumentTarget.java
class ArgumentTarget (line 10) | public class ArgumentTarget {
method arg0 (line 16) | public static void arg0() {
method arg1 (line 20) | public static void arg1(int v1) {
method arg1 (line 24) | public static void arg1(long v1) {
method arg2 (line 28) | public static void arg2(int v1, int v2) {
method arg2 (line 32) | public static void arg2(int v1, long v2) {
method arg2 (line 36) | public static void arg2(long v1, int v2) {
method arg2 (line 40) | public static void arg2(long v1, long v2) {
method arg3 (line 44) | public static void arg3(int v1, int v2, int v3) {
method arg3 (line 48) | public static void arg3(long v1, int v2, int v3) {
method arg3 (line 52) | public static void arg3(int v1, long v2, int v3) {
method arg3 (line 56) | public static void arg3(int v1, int v2, long v3) {
method arg3 (line 60) | public static void arg3(long v1, long v2, int v3) {
method arg3 (line 64) | public static void arg3(long v1, int v2, long v3) {
method arg3 (line 68) | public static void arg3(int v1, long v2, long v3) {
method arg3 (line 72) | public static void arg3(long v1, long v2, long v3) {
method arg4 (line 76) | public static void arg4(int v1, int v2, int v3, int v4) {
method arg4 (line 80) | public static void arg4(long v1, int v2, int v3, int v4) {
method arg4 (line 84) | public static void arg4(int v1, long v2, int v3, int v4) {
method arg4 (line 88) | public static void arg4(int v1, int v2, long v3, int v4) {
method arg4 (line 92) | public static void arg4(int v1, int v2, int v3, long v4) {
method arg4 (line 96) | public static void arg4(long v1, long v2, int v3, int v4) {
method arg4 (line 100) | public static void arg4(long v1, int v2, long v3, int v4) {
method arg4 (line 104) | public static void arg4(long v1, int v2, int v3, long v4) {
method arg4 (line 108) | public static void arg4(int v1, long v2, long v3, int v4) {
method arg4 (line 112) | public static void arg4(int v1, long v2, int v3, long v4) {
method arg4 (line 116) | public static void arg4(int v1, int v2, long v3, long v4) {
method arg4 (line 120) | public static void arg4(int v1, long v2, long v3, long v4) {
method arg4 (line 124) | public static void arg4(long v1, int v2, long v3, long v4) {
method arg4 (line 128) | public static void arg4(long v1, long v2, int v3, long v4) {
method arg4 (line 132) | public static void arg4(long v1, long v2, long v3, int v4) {
method arg4 (line 136) | public static void arg4(long v1, long v2, long v3, long v4) {
method arg5 (line 140) | public static void arg5(int v1, int v2, int v3, int v4, int v5) {
method arg5 (line 144) | public static void arg5(long v1, long v2, long v3, long v4, long v5) {
method arg6 (line 148) | public static void arg6(int v1, int v2, int v3, int v4, int v5, int v6) {
method arg6 (line 152) | public static void arg6(long v1, long v2, long v3, long v4, long v5, l...
method arg7 (line 156) | public static void arg7(int v1, int v2, int v3, int v4, int v5, int v6...
method arg7 (line 160) | public static void arg7(long v1, long v2, long v3, long v4, long v5, l...
method iarg0 (line 168) | public void iarg0() {
method iarg1 (line 172) | public void iarg1(int v1) {
method iarg1 (line 176) | public void iarg1(long v1) {
method iarg2 (line 180) | public void iarg2(int v1, int v2) {
method iarg2 (line 184) | public void iarg2(int v1, long v2) {
method iarg2 (line 188) | public void iarg2(long v1, long v2) {
method iarg3 (line 192) | public void iarg3(int v1, int v2, int v3) {
method iarg3 (line 196) | public void iarg3(long v1, int v2, int v3) {
method iarg3 (line 200) | public void iarg3(int v1, long v2, int v3) {
method iarg3 (line 204) | public void iarg3(int v1, int v2, long v3) {
method iarg3 (line 208) | public void iarg3(long v1, long v2, int v3) {
method iarg3 (line 212) | public void iarg3(long v1, int v2, long v3) {
method iarg3 (line 216) | public void iarg3(int v1, long v2, long v3) {
method iarg3 (line 220) | public void iarg3(long v1, long v2, long v3) {
FILE: app/src/main/java/me/weishu/epic/samples/tests/custom/Case.java
type Case (line 7) | public interface Case {
method hook (line 8) | void hook();
method validate (line 10) | boolean validate(Object... args);
FILE: app/src/main/java/me/weishu/epic/samples/tests/custom/Case1.java
class Case1 (line 15) | public class Case1 implements Case {
method hook (line 30) | @Override
method validate (line 52) | @Override
FILE: app/src/main/java/me/weishu/epic/samples/tests/custom/Case10_Default_Constructor.java
class Case10_Default_Constructor (line 15) | public class Case10_Default_Constructor implements Case {
method hook (line 19) | @Override
method validate (line 31) | @Override
FILE: app/src/main/java/me/weishu/epic/samples/tests/custom/Case11_SuspendAll.java
class Case11_SuspendAll (line 16) | public class Case11_SuspendAll implements Case {
method hook (line 20) | @Override
method validate (line 40) | @Override
FILE: app/src/main/java/me/weishu/epic/samples/tests/custom/Case12_MultiCallback.java
class Case12_MultiCallback (line 11) | public class Case12_MultiCallback implements Case {
method beforeHookedMethod (line 18) | @Override
method afterHookedMethod (line 25) | @Override
method beforeHookedMethod (line 34) | @Override
method afterHookedMethod (line 41) | @Override
method beforeHookedMethod (line 50) | @Override
method afterHookedMethod (line 57) | @Override
method hook (line 65) | @Override
method validate (line 72) | @Override
FILE: app/src/main/java/me/weishu/epic/samples/tests/custom/Case13_FastNative.java
class Case13_FastNative (line 13) | public class Case13_FastNative implements Case {
method hook (line 15) | @Override
method validate (line 22) | @Override
FILE: app/src/main/java/me/weishu/epic/samples/tests/custom/Case14_GC.java
class Case14_GC (line 12) | public class Case14_GC implements Case {
method hook (line 13) | @Override
method validate (line 19) | @Override
FILE: app/src/main/java/me/weishu/epic/samples/tests/custom/Case15_StopJit.java
class Case15_StopJit (line 9) | public class Case15_StopJit implements Case {
method hook (line 11) | @Override
method validate (line 16) | @Override
FILE: app/src/main/java/me/weishu/epic/samples/tests/custom/Case16_SameEntry.java
class Case16_SameEntry (line 18) | public class Case16_SameEntry implements Case {
method hook (line 21) | @Override
method validate (line 63) | @Override
FILE: app/src/main/java/me/weishu/epic/samples/tests/custom/Case17_SameMethod.java
class Case17_SameMethod (line 12) | public class Case17_SameMethod implements Case {
method hook (line 15) | @Override
method validate (line 46) | @Override
FILE: app/src/main/java/me/weishu/epic/samples/tests/custom/Case18_returnConst.java
class Case18_returnConst (line 13) | public class Case18_returnConst implements Case {
method hook (line 15) | @Override
method validate (line 33) | @Override
FILE: app/src/main/java/me/weishu/epic/samples/tests/custom/Case2.java
class Case2 (line 7) | public class Case2 implements Case{
method hook (line 10) | @Override
method validate (line 40) | @Override
FILE: app/src/main/java/me/weishu/epic/samples/tests/custom/Case3.java
class Case3 (line 12) | public class Case3 implements Case {
method hook (line 15) | @Override
method validate (line 32) | @Override
FILE: app/src/main/java/me/weishu/epic/samples/tests/custom/Case4.java
class Case4 (line 13) | public class Case4 implements Case {
method hook (line 16) | @Override
method validate (line 37) | @Override
FILE: app/src/main/java/me/weishu/epic/samples/tests/custom/Case5.java
class Case5 (line 18) | public class Case5 implements Case {
method hook (line 19) | @Override
method validate (line 52) | @Override
FILE: app/src/main/java/me/weishu/epic/samples/tests/custom/Case6.java
class Case6 (line 19) | public class Case6 implements Case {
method hook (line 23) | @Override
method validate (line 50) | @Override
FILE: app/src/main/java/me/weishu/epic/samples/tests/custom/Case7.java
class Case7 (line 14) | public class Case7 implements Case {
method hook (line 18) | @Override
method validate (line 32) | @Override
FILE: app/src/main/java/me/weishu/epic/samples/tests/custom/Case8_Activity_onCreate.java
class Case8_Activity_onCreate (line 14) | public class Case8_Activity_onCreate implements Case {
method hook (line 17) | @Override
method validate (line 34) | @Override
FILE: app/src/main/java/me/weishu/epic/samples/tests/custom/Case9_ThreadMonitor.java
class Case9_ThreadMonitor (line 14) | public class Case9_ThreadMonitor implements Case {
method hook (line 18) | @Override
method validate (line 58) | @Override
class MyThread (line 82) | static class MyThread extends Thread {
method run (line 83) | @Override
FILE: app/src/main/java/me/weishu/epic/samples/tests/custom/CaseManager.java
class CaseManager (line 11) | public class CaseManager {
method getInstance (line 17) | public static synchronized CaseManager getInstance() {
method getCase (line 21) | public synchronized Case getCase(Class<?> clazz) {
method getCases (line 36) | public synchronized Set<Class<?>> getCases() {
FILE: app/src/main/java/me/weishu/epic/samples/tests/custom/Target.java
class Target (line 15) | public class Target {
method Target (line 17) | public Target() {
method test1 (line 20) | public int test1(Object a, int b) {
method returnConst (line 38) | public int returnConst(int a) {
method add (line 42) | public int add(int a, int b) {
method plus (line 46) | public int plus(int a, int b) {
method test3 (line 50) | public int test3(Object a, int b) {
method test4 (line 55) | public static int test4(int a) {
method add (line 60) | public static float add(int a, float b) {
method test2 (line 64) | public static int test2(Object a, int b) {
method longRunMethod (line 70) | public long longRunMethod() {
method validate (line 75) | public static void validate() {
FILE: app/src/main/java/me/weishu/epic/samples/tests/invoketype/InvokeConstructor.java
class InvokeConstructor (line 12) | public class InvokeConstructor extends TestCase {
method InvokeConstructor (line 16) | public InvokeConstructor() {
method test (line 20) | @Override
method predicate (line 37) | @Override
FILE: app/src/main/java/me/weishu/epic/samples/tests/invoketype/InvokeTypeTarget.java
class InvokeTypeTarget (line 7) | public class InvokeTypeTarget {
FILE: app/src/main/java/me/weishu/epic/samples/tests/returntype/BooleanType.java
class BooleanType (line 11) | public class BooleanType extends TestCase {
method BooleanType (line 16) | public BooleanType() {
method test (line 20) | @Override
method predicate (line 32) | @Override
FILE: app/src/main/java/me/weishu/epic/samples/tests/returntype/ByteType.java
class ByteType (line 11) | public class ByteType extends TestCase {
method ByteType (line 16) | public ByteType() {
method test (line 20) | @Override
method predicate (line 32) | @Override
FILE: app/src/main/java/me/weishu/epic/samples/tests/returntype/CharType.java
class CharType (line 11) | public class CharType extends TestCase {
method CharType (line 16) | public CharType() {
method test (line 20) | @Override
method predicate (line 33) | @Override
FILE: app/src/main/java/me/weishu/epic/samples/tests/returntype/CustomType.java
class CustomType (line 11) | public class CustomType extends TestCase {
method CustomType (line 16) | public CustomType() {
method test (line 20) | @Override
method predicate (line 32) | @Override
FILE: app/src/main/java/me/weishu/epic/samples/tests/returntype/DoubleType.java
class DoubleType (line 11) | public class DoubleType extends TestCase {
method DoubleType (line 16) | public DoubleType() {
method test (line 20) | @Override
method predicate (line 33) | @Override
FILE: app/src/main/java/me/weishu/epic/samples/tests/returntype/FloatType.java
class FloatType (line 11) | public class FloatType extends TestCase {
method FloatType (line 16) | public FloatType() {
method test (line 20) | @Override
method predicate (line 33) | @Override
FILE: app/src/main/java/me/weishu/epic/samples/tests/returntype/IntType.java
class IntType (line 11) | public class IntType extends TestCase {
method IntType (line 16) | public IntType() {
method test (line 20) | @Override
method predicate (line 33) | @Override
FILE: app/src/main/java/me/weishu/epic/samples/tests/returntype/LongType.java
class LongType (line 11) | public class LongType extends TestCase {
method LongType (line 16) | public LongType() {
method test (line 20) | @Override
method predicate (line 33) | @Override
FILE: app/src/main/java/me/weishu/epic/samples/tests/returntype/ReturnTypeTarget.java
class ReturnTypeTarget (line 9) | public class ReturnTypeTarget {
method returnVoid (line 12) | public static void returnVoid() {
method returnByte (line 16) | public static byte returnByte(byte b) {
method returnChar (line 21) | public static char returnChar(char c) {
method returnShort (line 26) | public static short returnShort(short s) {
method returnInt (line 31) | public static int returnInt(int i) {
method returnLong (line 36) | public static long returnLong(long l) {
method returnFloat (line 41) | public static float returnFloat(float f) {
method returnDouble (line 46) | public static double returnDouble(double d) {
method returnBoolean (line 51) | public static boolean returnBoolean(boolean b) {
method returnString (line 56) | public static String returnString(String s) {
method returnStringArray (line 61) | public static String[] returnStringArray(String[] a) {
method returnCustom (line 66) | public static ReturnTypeTarget returnCustom(ReturnTypeTarget r) {
FILE: app/src/main/java/me/weishu/epic/samples/tests/returntype/ShortType.java
class ShortType (line 11) | public class ShortType extends TestCase {
method ShortType (line 16) | public ShortType() {
method test (line 20) | @Override
method predicate (line 32) | @Override
FILE: app/src/main/java/me/weishu/epic/samples/tests/returntype/StringArrayType.java
class StringArrayType (line 11) | public class StringArrayType extends TestCase {
method StringArrayType (line 16) | public StringArrayType() {
method test (line 20) | @Override
method predicate (line 33) | @Override
FILE: app/src/main/java/me/weishu/epic/samples/tests/returntype/StringType.java
class StringType (line 11) | public class StringType extends TestCase {
method StringType (line 16) | public StringType() {
method test (line 20) | @Override
method predicate (line 33) | @Override
FILE: app/src/main/java/me/weishu/epic/samples/tests/returntype/VoidType.java
class VoidType (line 13) | public class VoidType extends TestCase {
method VoidType (line 20) | public VoidType() {
method test (line 24) | @Override
method predicate (line 41) | @Override
FILE: library/src/main/cpp/art.cpp
function find_offset (line 29) | inline int find_offset(void* hay, int size, T needle)
FILE: library/src/main/cpp/art.h
type Runtime_7X (line 31) | struct Runtime_7X {
type Runtime_8X (line 70) | struct Runtime_8X {
type PartialRuntimeR (line 112) | struct PartialRuntimeR {
type JavaVMExt (line 146) | struct JavaVMExt {
function class (line 151) | class ArtHelper {
FILE: library/src/main/cpp/epic.cpp
class ScopedSuspendAll (line 53) | class ScopedSuspendAll {}
class ScopedJitSuspend (line 58) | class ScopedJitSuspend {}
function init_entries (line 82) | void init_entries(JNIEnv *env) {
function jboolean (line 140) | jboolean epic_compile(JNIEnv *env, jclass, jobject method, jlong self) {
function jlong (line 170) | jlong epic_suspendAll(JNIEnv *, jclass) {
function epic_resumeAll (line 176) | void epic_resumeAll(JNIEnv* env, jclass, jlong obj) {
function jlong (line 181) | jlong epic_stopJit(JNIEnv*, jclass) {
function epic_startJit (line 187) | void epic_startJit(JNIEnv*, jclass, jlong obj) {
function epic_disableMovingGc (line 192) | void epic_disableMovingGc(JNIEnv* env, jclass ,jint api) {
function jboolean (line 197) | jboolean epic_munprotect(JNIEnv *env, jclass, jlong addr, jlong len) {
function jboolean (line 211) | jboolean epic_cacheflush(JNIEnv *env, jclass, jlong addr, jlong len) {
function epic_MakeInitializedClassVisibilyInitialized (line 227) | void epic_MakeInitializedClassVisibilyInitialized(JNIEnv *env, jclass, j...
function epic_memcpy (line 233) | void epic_memcpy(JNIEnv *env, jclass, jlong src, jlong dest, jint length) {
function epic_memput (line 241) | void epic_memput(JNIEnv *env, jclass, jbyteArray src, jlong dest) {
function jbyteArray (line 253) | jbyteArray epic_memget(JNIEnv *env, jclass, jlong src, jint length) {
function jlong (line 269) | jlong epic_mmap(JNIEnv *env, jclass, jint length) {
function epic_munmap (line 279) | void epic_munmap(JNIEnv *env, jclass, jlong addr, jint length) {
function jlong (line 286) | jlong epic_malloc(JNIEnv *env, jclass, jint size) {
function jobject (line 294) | jobject epic_getobject(JNIEnv *env, jclass clazz, jlong self, jlong addr...
function jlong (line 305) | jlong epic_getMethodAddress(JNIEnv *env, jclass clazz, jobject method) {
function jboolean (line 313) | jboolean epic_isGetObjectAvaliable(JNIEnv *, jclass) {
function jboolean (line 317) | jboolean epic_activate(JNIEnv* env, jclass jclazz, jlong jumpToAddress, ...
function registerNativeMethods (line 388) | static int registerNativeMethods(JNIEnv *env, const char *className,
function JNIEXPORT (line 403) | JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
FILE: library/src/main/cpp/fake_dlfcn.cpp
type ctx (line 59) | struct ctx {
function fake_dlclose (line 69) | static int fake_dlclose(void *handle) {
type ctx (line 83) | struct ctx
type ctx (line 120) | struct ctx
type ctx (line 120) | struct ctx
type ctx (line 246) | struct ctx
type ctx (line 246) | struct ctx
function get_sdk_level (line 268) | static int get_sdk_level() {
function dlclose_ex (line 278) | int dlclose_ex(void *handle) {
FILE: library/src/main/java/com/taobao/android/dexposed/ClassUtils.java
class ClassUtils (line 43) | public class ClassUtils {
method addAbbreviation (line 115) | private static void addAbbreviation(String primitive, String abbreviat...
method ClassUtils (line 142) | public ClassUtils() {
method getShortClassName (line 155) | public static String getShortClassName(Object object, String valueIfNu...
method getShortClassName (line 172) | public static String getShortClassName(Class<?> cls) {
method getShortClassName (line 191) | public static String getShortClassName(String className) {
method getSimpleName (line 235) | public static String getSimpleName(Class<?> cls) {
method getSimpleName (line 251) | public static String getSimpleName(Object object, String valueIfNull) {
method getPackageName (line 267) | public static String getPackageName(Object object, String valueIfNull) {
method getPackageName (line 280) | public static String getPackageName(Class<?> cls) {
method getPackageName (line 296) | public static String getPackageName(String className) {
method getAllSuperclasses (line 326) | public static List<Class<?>> getAllSuperclasses(Class<?> cls) {
method getAllInterfaces (line 352) | public static List<Class<?>> getAllInterfaces(Class<?> cls) {
method getAllInterfaces (line 369) | private static void getAllInterfaces(Class<?> cls, HashSet<Class<?>> i...
method convertClassNamesToClasses (line 397) | public static List<Class<?>> convertClassNamesToClasses(List<String> c...
method convertClassesToClassNames (line 424) | public static List<String> convertClassesToClassNames(List<Class<?>> c...
method getClass (line 453) | public static Class<?> getClass(
method getClass (line 494) | public static Class<?> getClass(ClassLoader classLoader, String classN...
method getClass (line 509) | public static Class<?> getClass(String className) throws ClassNotFound...
method getClass (line 524) | public static Class<?> getClass(String className, boolean initialize) ...
method toCanonicalName (line 537) | private static String toCanonicalName(String className) {
method toClass (line 568) | public static Class<?>[] toClass(Object... array) {
method deleteWhitespace (line 597) | public static String deleteWhitespace(String str) {
method isEmpty (line 636) | public static boolean isEmpty(CharSequence cs) {
FILE: library/src/main/java/com/taobao/android/dexposed/DeviceCheck.java
class DeviceCheck (line 30) | public class DeviceCheck {
method isDalvikMode (line 40) | private static boolean isDalvikMode() {
method getCurrentRuntimeValue (line 48) | private static String getCurrentRuntimeValue() {
method isSupportSDKVersion (line 86) | private static boolean isSupportSDKVersion() {
method isX86CPU (line 95) | private static boolean isX86CPU() {
method isDeviceSupport (line 135) | public static synchronized boolean isDeviceSupport(Context context) {
method isYunOS (line 153) | @SuppressLint("DefaultLocale")
FILE: library/src/main/java/com/taobao/android/dexposed/utility/Debug.java
class Debug (line 30) | public final class Debug {
method Debug (line 36) | private Debug() {
method addrHex (line 39) | public static String addrHex(long i) {
method longHex (line 51) | public static String longHex(long i) {
method intHex (line 55) | public static String intHex(int i) {
method byteHex (line 59) | public static String byteHex(byte b) {
method dump (line 63) | public static String dump(byte[] b, long start) {
method hexdump (line 76) | public static String hexdump(byte[] bytes, long start) {
method methodDescription (line 93) | public static String methodDescription(Method method) {
method dumpMaps (line 99) | public static void dumpMaps() {
FILE: library/src/main/java/com/taobao/android/dexposed/utility/Logger.java
class Logger (line 8) | public class Logger {
method i (line 14) | public static void i(String tag, String msg) {
method d (line 20) | public static void d(String tagSuffix, String msg) {
method w (line 26) | public static void w(String tag, String msg) {
method e (line 30) | public static void e(String tag, String msg) {
method e (line 36) | public static void e(String tag, String msg, Throwable e) {
FILE: library/src/main/java/com/taobao/android/dexposed/utility/NeverCalled.java
class NeverCalled (line 9) | public class NeverCalled {
method fake (line 10) | private void fake(int a) {
FILE: library/src/main/java/com/taobao/android/dexposed/utility/NougatPolicy.java
class NougatPolicy (line 9) | public class NougatPolicy {
class TraceLogger (line 11) | private static class TraceLogger {
method i (line 12) | static void i(String tag, String msg) {
method e (line 15) | static void e(String tag, String msg) {
method e (line 18) | static void e(String tag, String msg, Throwable e) {
method fullCompile (line 25) | public static boolean fullCompile(Context context) {
method clearCompileData (line 54) | public static boolean clearCompileData(Context context) {
method getPackageManagerBinderProxy (line 68) | private static Object getPackageManagerBinderProxy() throws Exception {
FILE: library/src/main/java/com/taobao/android/dexposed/utility/Platform.java
class Platform (line 23) | public abstract class Platform {
method getPlatform (line 35) | public static Platform getPlatform() {
method orderByteToInt (line 46) | public abstract int orderByteToInt(byte[] data);
method orderByteToLong (line 55) | public abstract long orderByteToLong(byte[] data);
method orderLongToByte (line 57) | public abstract byte[] orderLongToByte(long serial, int length);
method orderIntToByte (line 59) | public abstract byte[] orderIntToByte(int serial);
method getIntSize (line 61) | public abstract int getIntSize();
class Platform32Bit (line 64) | static class Platform32Bit extends Platform {
method orderByteToInt (line 66) | @Override
method orderByteToLong (line 71) | @Override
method orderLongToByte (line 76) | @Override
method orderIntToByte (line 81) | @Override
method getIntSize (line 86) | @Override
class Platform64Bit (line 94) | static class Platform64Bit extends Platform {
method orderByteToInt (line 96) | @Override
method orderByteToLong (line 101) | @Override
method orderLongToByte (line 106) | @Override
method orderIntToByte (line 111) | @Override
method getIntSize (line 116) | @Override
FILE: library/src/main/java/com/taobao/android/dexposed/utility/Runtime.java
class Runtime (line 26) | public class Runtime {
method is64Bit (line 46) | public static boolean is64Bit() {
method isArt (line 50) | public static boolean isArt() {
method isThumb2 (line 54) | public static boolean isThumb2() {
FILE: library/src/main/java/com/taobao/android/dexposed/utility/Unsafe.java
class Unsafe (line 23) | public final class Unsafe {
method Unsafe (line 46) | private Unsafe() {
method arrayBaseOffset (line 49) | @SuppressWarnings("unchecked")
method arrayIndexScale (line 59) | @SuppressWarnings("unchecked")
method objectFieldOffset (line 69) | @SuppressWarnings("unchecked")
method getInt (line 79) | @SuppressWarnings("unchecked")
method getLong (line 89) | @SuppressWarnings("unchecked")
method putLong (line 99) | @SuppressWarnings("unchecked")
method putInt (line 112) | @SuppressWarnings("unchecked")
method getObjectAddress (line 125) | public static long getObjectAddress(Object obj) {
method getObject (line 144) | public static Object getObject(long address) {
FILE: library/src/main/java/de/robv/android/xposed/DexposedBridge.java
class DexposedBridge (line 47) | public final class DexposedBridge {
method log (line 81) | public synchronized static void log(String text) {
method log (line 90) | public synchronized static void log(Throwable t) {
method hookMethod (line 100) | public static XC_MethodHook.Unhook hookMethod(Member hookMethod, XC_Me...
method unhookMethod (line 152) | public static void unhookMethod(Member hookMethod, XC_MethodHook callb...
method hookAllMethods (line 162) | public static Set<XC_MethodHook.Unhook> hookAllMethods(Class<?> hookCl...
method findAndHookMethod (line 170) | public static XC_MethodHook.Unhook findAndHookMethod(Class<?> clazz, S...
method unhookAllMethods (line 183) | public static void unhookAllMethods() {
method hookAllConstructors (line 192) | public static Set<XC_MethodHook.Unhook> hookAllConstructors(Class<?> h...
method handleHookedArtMethod (line 200) | public static Object handleHookedArtMethod(Object artMethodObject, Obj...
method throwNoCheck (line 307) | @SuppressWarnings("unchecked")
method handleHookedMethod (line 315) | private static Object handleHookedMethod(Member method, int originalMe...
method invokeSuperNative (line 394) | private native static Object invokeSuperNative(Object obj, Object[] ar...
method invokeSuper (line 399) | public static Object invokeSuper(Object obj, Member method, Object... ...
method hookMethodNative (line 424) | private native synchronized static void hookMethodNative(Member method...
method invokeOriginalMethodNative (line 426) | private native static Object invokeOriginalMethodNative(Member method,...
method invokeOriginalMethod (line 451) | public static Object invokeOriginalMethod(Member method, Object thisOb...
class CopyOnWriteSortedSet (line 485) | public static class CopyOnWriteSortedSet<E> {
method add (line 488) | public synchronized boolean add(E e) {
method remove (line 501) | public synchronized boolean remove(E e) {
method clear (line 513) | public synchronized void clear(){
method indexOf (line 517) | private int indexOf(Object o) {
method getSnapshot (line 525) | public Object[] getSnapshot() {
class AdditionalHookInfo (line 530) | private static class AdditionalHookInfo {
method AdditionalHookInfo (line 535) | private AdditionalHookInfo(CopyOnWriteSortedSet<XC_MethodHook> callb...
FILE: library/src/main/java/me/weishu/epic/art/Epic.java
class Epic (line 42) | public final class Epic {
method hookMethod (line 74) | public static boolean hookMethod(Constructor origin) {
method hookMethod (line 78) | public static boolean hookMethod(Method origin) {
method hookMethod (line 83) | private static boolean hookMethod(ArtMethod artOrigin) {
method getBackMethod (line 176) | public synchronized static ArtMethod getBackMethod(ArtMethod origin) {
method setBackMethod (line 181) | public static synchronized void setBackMethod(ArtMethod origin, ArtMet...
method getMethodInfo (line 186) | public static MethodInfo getMethodInfo(long address) {
method getQuickCompiledCodeSize (line 190) | public static int getQuickCompiledCodeSize(ArtMethod method) {
class MethodInfo (line 201) | public static class MethodInfo {
method toString (line 208) | @Override
class EntryLock (line 214) | private static class EntryLock {
method obtain (line 217) | static synchronized EntryLock obtain(long entry) {
FILE: library/src/main/java/me/weishu/epic/art/EpicNative.java
class EpicNative (line 33) | public final class EpicNative {
method mmap (line 47) | public static native long mmap(int length);
method munmap (line 49) | public static native boolean munmap(long address, int length);
method memcpy (line 51) | public static native void memcpy(long src, long dest, int length);
method memput (line 53) | public static native void memput(byte[] bytes, long dest);
method memget (line 55) | public static native byte[] memget(long src, int length);
method munprotect (line 57) | public static native boolean munprotect(long addr, long len);
method getMethodAddress (line 59) | public static native long getMethodAddress(Member method);
method MakeInitializedClassVisibilyInitialized (line 61) | public static native void MakeInitializedClassVisibilyInitialized(long...
method cacheflush (line 63) | public static native boolean cacheflush(long addr, long len);
method malloc (line 65) | public static native long malloc(int sizeOfPtr);
method getObjectNative (line 67) | public static native Object getObjectNative(long self, long address);
method isGetObjectAvailable (line 69) | private static native boolean isGetObjectAvailable();
method getObject (line 71) | public static Object getObject(long self, long address) {
method compileMethod (line 79) | public static native boolean compileMethod(Member method, long self);
method suspendAll (line 85) | public static native long suspendAll();
method resumeAll (line 92) | public static native void resumeAll(long cookie);
method stopJit (line 99) | public static native long stopJit();
method startJit (line 106) | public static native void startJit(long cookie);
method activateNative (line 109) | static native boolean activateNative(long jumpToAddress, long pc, long...
method disableMovingGc (line 116) | public static native void disableMovingGc(int api);
method EpicNative (line 119) | private EpicNative() {
method compileMethod (line 122) | public static boolean compileMethod(Member method) {
method getObject (line 127) | public static Object getObject(long address) {
method MakeInitializedClassVisibilyInitialized (line 132) | public static void MakeInitializedClassVisibilyInitialized() {
method map (line 137) | public static long map(int length) {
method unmap (line 143) | public static boolean unmap(long address, int length) {
method put (line 148) | public static void put(byte[] bytes, long dest) {
method get (line 156) | public static byte[] get(long src, int length) {
method unprotect (line 163) | public static boolean unprotect(long addr, long len) {
method copy (line 168) | public static void copy(long src, long dst, int length) {
FILE: library/src/main/java/me/weishu/epic/art/Trampoline.java
class Trampoline (line 32) | class Trampoline {
method Trampoline (line 45) | Trampoline(ShellCode shellCode, long entryPoint) {
method install (line 51) | public boolean install(ArtMethod originMethod){
method getTrampolineAddress (line 74) | private long getTrampolineAddress() {
method getTrampolinePc (line 81) | private long getTrampolinePc() {
method alloc (line 85) | private void alloc() {
method free (line 94) | private void free() {
method getSize (line 106) | private int getSize() {
method create (line 113) | private byte[] create() {
method activate (line 131) | private boolean activate() {
method finalize (line 140) | @Override
method createTrampoline (line 146) | private byte[] createTrampoline(ArtMethod source){
FILE: library/src/main/java/me/weishu/epic/art/arch/Arm64.java
class Arm64 (line 21) | public class Arm64 extends ShellCode {
method sizeOfDirectJump (line 23) | @Override
method createDirectJump (line 28) | @Override
method createBridgeJump (line 40) | @Override
method sizeOfBridgeJump (line 84) | @Override
method toPC (line 90) | @Override
method toMem (line 95) | @Override
method getName (line 100) | @Override
FILE: library/src/main/java/me/weishu/epic/art/arch/Arm64_2.java
class Arm64_2 (line 21) | public class Arm64_2 extends ShellCode {
method sizeOfDirectJump (line 23) | @Override
method createDirectJump (line 28) | @Override
method createBridgeJump (line 40) | @Override
method sizeOfBridgeJump (line 106) | @Override
method toPC (line 112) | @Override
method toMem (line 117) | @Override
method getName (line 122) | @Override
FILE: library/src/main/java/me/weishu/epic/art/arch/ShellCode.java
class ShellCode (line 22) | public abstract class ShellCode {
method createDirectJump (line 24) | public abstract byte[] createDirectJump(long targetAddress);
method sizeOfDirectJump (line 26) | public abstract int sizeOfDirectJump();
method toPC (line 28) | public abstract long toPC(long code);
method toMem (line 30) | public abstract long toMem(long pc);
method createCallOrigin (line 32) | public byte[] createCallOrigin(long originalAddress, byte[] originalPr...
method sizeOfCallOrigin (line 40) | public int sizeOfCallOrigin() {
method sizeOfBridgeJump (line 44) | public abstract int sizeOfBridgeJump();
method createBridgeJump (line 46) | public byte[] createBridgeJump(long targetAddress, long targetEntry, l...
method writeInt (line 50) | static void writeInt(int i, ByteOrder order, byte[] target, int pos) {
method writeLong (line 54) | static void writeLong(long i, ByteOrder order, byte[] target, int pos) {
method getName (line 58) | public abstract String getName();
FILE: library/src/main/java/me/weishu/epic/art/arch/Thumb2.java
class Thumb2 (line 22) | public class Thumb2 extends ShellCode {
method sizeOfDirectJump (line 24) | @Override
method createDirectJump (line 29) | @Override
method createBridgeJump (line 40) | @Override
method sizeOfBridgeJump (line 107) | @Override
method toPC (line 112) | @Override
method toMem (line 117) | @Override
method getName (line 122) | @Override
FILE: library/src/main/java/me/weishu/epic/art/entry/Entry.java
class Entry (line 36) | @SuppressWarnings({"unused", "ConstantConditions"})
method onHookInt (line 44) | private static int onHookInt(Object artmethod, Object receiver, Object...
method onHookLong (line 48) | private static long onHookLong(Object artmethod, Object receiver, Obje...
method onHookDouble (line 52) | private static double onHookDouble(Object artmethod, Object receiver, ...
method onHookChar (line 56) | private static char onHookChar(Object artmethod, Object receiver, Obje...
method onHookShort (line 60) | private static short onHookShort(Object artmethod, Object receiver, Ob...
method onHookFloat (line 64) | private static float onHookFloat(Object artmethod, Object receiver, Ob...
method onHookObject (line 68) | private static Object onHookObject(Object artmethod, Object receiver, ...
method onHookVoid (line 72) | private static void onHookVoid(Object artmethod, Object receiver, Obje...
method onHookBoolean (line 76) | private static boolean onHookBoolean(Object artmethod, Object receiver...
method onHookByte (line 80) | private static byte onHookByte(Object artmethod, Object receiver, Obje...
method voidBridge (line 86) | private static void voidBridge(int r1, int self, int struct) {
method booleanBridge (line 90) | private static boolean booleanBridge(int r1, int self, int struct) {
method byteBridge (line 94) | private static byte byteBridge(int r1, int self, int struct) {
method shortBridge (line 98) | private static short shortBridge(int r1, int self, int struct) {
method charBridge (line 102) | private static char charBridge(int r1, int self, int struct) {
method intBridge (line 106) | private static int intBridge(int r1, int self, int struct) {
method longBridge (line 110) | private static long longBridge(int r1, int self, int struct) {
method floatBridge (line 114) | private static float floatBridge(int r1, int self, int struct) {
method doubleBridge (line 118) | private static double doubleBridge(int r1, int self, int struct) {
method referenceBridge (line 123) | private static Object referenceBridge(int r1, int self, int struct) {
method constructArguments (line 206) | private static Pair<Object, Object[]> constructArguments(Epic.MethodIn...
method wrapArgument (line 372) | private static Object wrapArgument(Class<?> type, int self, byte[] val...
method getBridgeMethod (line 415) | public static Method getBridgeMethod(Class<?> returnType) {
method getTypeLength (line 427) | private static int getTypeLength(Class<?> clazz) {
FILE: library/src/main/java/me/weishu/epic/art/entry/Entry64.java
class Entry64 (line 33) | @SuppressWarnings({"unused", "ConstantConditions"})
method onHookInt (line 39) | private static int onHookInt(Object artmethod, Object receiver, Object...
method onHookLong (line 43) | private static long onHookLong(Object artmethod, Object receiver, Obje...
method onHookDouble (line 47) | private static double onHookDouble(Object artmethod, Object receiver, ...
method onHookChar (line 51) | private static char onHookChar(Object artmethod, Object receiver, Obje...
method onHookShort (line 55) | private static short onHookShort(Object artmethod, Object receiver, Ob...
method onHookFloat (line 59) | private static float onHookFloat(Object artmethod, Object receiver, Ob...
method onHookObject (line 63) | private static Object onHookObject(Object artmethod, Object receiver, ...
method onHookVoid (line 67) | private static void onHookVoid(Object artmethod, Object receiver, Obje...
method onHookBoolean (line 71) | private static boolean onHookBoolean(Object artmethod, Object receiver...
method onHookByte (line 75) | private static byte onHookByte(Object artmethod, Object receiver, Obje...
method voidBridge (line 81) | private static void voidBridge(long r1, long self, long struct, long x...
method booleanBridge (line 85) | private static boolean booleanBridge(long r1, long self, long struct, ...
method byteBridge (line 89) | private static byte byteBridge(long r1, long self, long struct, long x...
method shortBridge (line 93) | private static short shortBridge(long r1, long self, long struct, long...
method charBridge (line 97) | private static char charBridge(long r1, long self, long struct, long x...
method intBridge (line 101) | private static int intBridge(long r1, long self, long struct, long x4,...
method longBridge (line 105) | private static long longBridge(long r1, long self, long struct, long x...
method floatBridge (line 109) | private static float floatBridge(long r1, long self, long struct, long...
method doubleBridge (line 113) | private static double doubleBridge(long r1, long self, long struct, lo...
method referenceBridge (line 118) | private static Object referenceBridge(long x1, long self, long struct,...
method wrapArgument (line 243) | private static Object wrapArgument(Class<?> type, long self, long valu...
method wrapArgument (line 247) | private static Object wrapArgument(Class<?> type, long self, byte[] va...
method getBridgeMethod (line 288) | public static Method getBridgeMethod(Class<?> returnType) {
FILE: library/src/main/java/me/weishu/epic/art/entry/Entry64_2.java
class Entry64_2 (line 34) | @SuppressWarnings({"unused", "ConstantConditions"})
method onHookInt (line 40) | private static int onHookInt(Object artmethod, Object receiver, Object...
method onHookLong (line 44) | private static long onHookLong(Object artmethod, Object receiver, Obje...
method onHookDouble (line 48) | private static double onHookDouble(Object artmethod, Object receiver, ...
method onHookChar (line 52) | private static char onHookChar(Object artmethod, Object receiver, Obje...
method onHookShort (line 56) | private static short onHookShort(Object artmethod, Object receiver, Ob...
method onHookFloat (line 60) | private static float onHookFloat(Object artmethod, Object receiver, Ob...
method onHookObject (line 64) | private static Object onHookObject(Object artmethod, Object receiver, ...
method onHookVoid (line 68) | private static void onHookVoid(Object artmethod, Object receiver, Obje...
method onHookBoolean (line 72) | private static boolean onHookBoolean(Object artmethod, Object receiver...
method onHookByte (line 76) | private static byte onHookByte(Object artmethod, Object receiver, Obje...
method voidBridge (line 82) | private static void voidBridge(long x1, long struct) {
method voidBridge (line 86) | private static void voidBridge(long x1, long struct, long x3) {
method voidBridge (line 90) | private static void voidBridge(long x1, long struct, long x3, long x4) {
method voidBridge (line 94) | private static void voidBridge(long r1, long struct, long x3, long x4,...
method voidBridge (line 98) | private static void voidBridge(long r1, long struct, long x3, long x4,...
method voidBridge (line 102) | private static void voidBridge(long r1, long struct, long x3, long x4,...
method booleanBridge (line 108) | private static boolean booleanBridge(long x1, long struct) {
method booleanBridge (line 112) | private static boolean booleanBridge(long x1, long struct, long x3) {
method booleanBridge (line 116) | private static boolean booleanBridge(long x1, long struct, long x3, lo...
method booleanBridge (line 120) | private static boolean booleanBridge(long r1, long struct, long x3, lo...
method booleanBridge (line 124) | private static boolean booleanBridge(long r1, long struct, long x3, lo...
method booleanBridge (line 128) | private static boolean booleanBridge(long r1, long struct, long x3, lo...
method byteBridge (line 134) | private static byte byteBridge(long x1, long struct) {
method byteBridge (line 138) | private static byte byteBridge(long x1, long struct, long x3) {
method byteBridge (line 142) | private static byte byteBridge(long x1, long struct, long x3, long x4) {
method byteBridge (line 146) | private static byte byteBridge(long r1, long struct, long x3, long x4,...
method byteBridge (line 150) | private static byte byteBridge(long r1, long struct, long x3, long x4,...
method byteBridge (line 154) | private static byte byteBridge(long r1, long struct, long x3, long x4,...
method shortBridge (line 160) | private static short shortBridge(long x1, long struct) {
method shortBridge (line 164) | private static short shortBridge(long x1, long struct, long x3) {
method shortBridge (line 168) | private static short shortBridge(long x1, long struct, long x3, long x...
method shortBridge (line 172) | private static short shortBridge(long r1, long struct, long x3, long x...
method shortBridge (line 176) | private static short shortBridge(long r1, long struct, long x3, long x...
method shortBridge (line 180) | private static short shortBridge(long r1, long struct, long x3, long x...
method charBridge (line 186) | private static char charBridge(long x1, long struct) {
method charBridge (line 190) | private static char charBridge(long x1, long struct, long x3) {
method charBridge (line 194) | private static char charBridge(long x1, long struct, long x3, long x4) {
method charBridge (line 198) | private static char charBridge(long r1, long struct, long x3, long x4,...
method charBridge (line 202) | private static char charBridge(long r1, long struct, long x3, long x4,...
method charBridge (line 206) | private static char charBridge(long r1, long struct, long x3, long x4,...
method intBridge (line 212) | private static int intBridge(long x1, long struct) {
method intBridge (line 216) | private static int intBridge(long x1, long struct, long x3) {
method intBridge (line 220) | private static int intBridge(long x1, long struct, long x3, long x4) {
method intBridge (line 224) | private static int intBridge(long r1, long struct, long x3, long x4, l...
method intBridge (line 228) | private static int intBridge(long r1, long struct, long x3, long x4, l...
method intBridge (line 232) | private static int intBridge(long r1, long struct, long x3, long x4, l...
method longBridge (line 238) | private static long longBridge(long x1, long struct) {
method longBridge (line 242) | private static long longBridge(long x1, long struct, long x3) {
method longBridge (line 246) | private static long longBridge(long x1, long struct, long x3, long x4) {
method longBridge (line 250) | private static long longBridge(long r1, long struct, long x3, long x4,...
method longBridge (line 254) | private static long longBridge(long r1, long struct, long x3, long x4,...
method longBridge (line 258) | private static long longBridge(long r1, long struct, long x3, long x4,...
method floatBridge (line 264) | private static float floatBridge(long x1, long struct) {
method floatBridge (line 268) | private static float floatBridge(long x1, long struct, long x3) {
method floatBridge (line 272) | private static float floatBridge(long x1, long struct, long x3, long x...
method floatBridge (line 276) | private static float floatBridge(long r1, long struct, long x3, long x...
method floatBridge (line 280) | private static float floatBridge(long r1, long struct, long x3, long x...
method floatBridge (line 284) | private static float floatBridge(long r1, long struct, long x3, long x...
method doubleBridge (line 290) | private static double doubleBridge(long x1, long struct) {
method doubleBridge (line 294) | private static double doubleBridge(long x1, long struct, long x3) {
method doubleBridge (line 298) | private static double doubleBridge(long x1, long struct, long x3, long...
method doubleBridge (line 302) | private static double doubleBridge(long r1, long struct, long x3, long...
method doubleBridge (line 306) | private static double doubleBridge(long r1, long struct, long x3, long...
method doubleBridge (line 310) | private static double doubleBridge(long r1, long struct, long x3, long...
method referenceBridge (line 316) | private static Object referenceBridge(long x1, long struct) {
method referenceBridge (line 320) | private static Object referenceBridge(long x1, long struct, long x3) {
method referenceBridge (line 324) | private static Object referenceBridge(long x1, long struct, long x3, l...
method referenceBridge (line 328) | private static Object referenceBridge(long r1, long struct, long x3, l...
method referenceBridge (line 332) | private static Object referenceBridge(long r1, long struct, long x3, l...
method referenceBridge (line 337) | private static Object referenceBridge(long x1, long struct, long x3, l...
method wrapArgument (line 456) | private static Object wrapArgument(Class<?> type, long self, long valu...
method wrapArgument (line 460) | private static Object wrapArgument(Class<?> type, long self, byte[] va...
method getBridgeMethod (line 501) | public static Method getBridgeMethod(Epic.MethodInfo methodInfo) {
FILE: library/src/main/java/me/weishu/epic/art/method/ArtMethod.java
class ArtMethod (line 41) | public class ArtMethod {
method ArtMethod (line 73) | private ArtMethod(Constructor constructor) {
method ArtMethod (line 81) | private ArtMethod(Method method, long address) {
method init (line 93) | private void init() {
method of (line 101) | public static ArtMethod of(Method method) {
method of (line 105) | public static ArtMethod of(Method method, long address) {
method of (line 109) | public static ArtMethod of(Constructor constructor) {
method backup (line 114) | public ArtMethod backup() {
method isAccessible (line 193) | public boolean isAccessible() {
method setAccessible (line 205) | public void setAccessible(boolean accessible) {
method getName (line 217) | public String getName() {
method getDeclaringClass (line 225) | public Class<?> getDeclaringClass() {
method compile (line 238) | public boolean compile() {
method invoke (line 255) | public Object invoke(Object receiver, Object... args) throws IllegalAc...
method invokeInternal (line 277) | private Object invokeInternal(Object receiver, Object... args) throws ...
method getModifiers (line 289) | public int getModifiers() {
method getParameterTypes (line 301) | public Class<?>[] getParameterTypes() {
method getReturnType (line 313) | public Class<?> getReturnType() {
method getExceptionTypes (line 325) | public Class<?>[] getExceptionTypes() {
method toGenericString (line 333) | public String toGenericString() {
method getExecutable (line 344) | public Object getExecutable() {
method getAddress (line 356) | public long getAddress() {
method getIdentifier (line 364) | public String getIdentifier() {
method makePrivate (line 372) | public void makePrivate() {
method ensureResolved (line 383) | public void ensureResolved() {
method getEntryPointFromQuickCompiledCode (line 403) | public long getEntryPointFromQuickCompiledCode() {
method setEntryPointFromQuickCompiledCode (line 410) | public void setEntryPointFromQuickCompiledCode(long pointer_entry_poin...
method getAccessFlags (line 417) | public int getAccessFlags() {
method setAccessFlags (line 421) | public void setAccessFlags(int newFlags) {
method setEntryPointFromJni (line 425) | public void setEntryPointFromJni(long entryPointFromJni) {
method getEntryPointFromJni (line 429) | public long getEntryPointFromJni() {
method getArtMethodSize (line 437) | public static int getArtMethodSize() {
method rule1 (line 451) | private void rule1() {
method rule2 (line 455) | private void rule2() {
method getQuickToInterpreterBridge (line 458) | public static long getQuickToInterpreterBridge() {
method getFieldOffset (line 466) | public long getFieldOffset() {
method searchOffset (line 478) | public static long searchOffset(long base, long range, int value) {
method searchOffset (line 492) | public static long searchOffset(long base, long range, long value) {
FILE: library/src/main/java/me/weishu/epic/art/method/Offset.java
class Offset (line 33) | class Offset {
type BitWidth (line 56) | private enum BitWidth {
method BitWidth (line 60) | BitWidth(int width) {
method getOffset (line 70) | public long getOffset() {
method setOffset (line 74) | public void setOffset(long offset) {
method getLength (line 78) | public BitWidth getLength() {
method setLength (line 82) | public void setLength(BitWidth length) {
method read (line 86) | public static long read(long base, Offset offset) {
method write (line 96) | public static void write(long base, Offset offset, long value) {
method initFields (line 111) | private static void initFields() {
Condensed preview — 137 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (384K chars).
[
{
"path": ".github/FUNDING.yml",
"chars": 568,
"preview": "# These are supported funding model platforms\n\ngithub: # replace\npatreon: weishu\nopen_collective: # Replace with a singl"
},
{
"path": ".github/workflows/android.yml",
"chars": 273,
"preview": "name: Android CI\n\non: [push]\n\njobs:\n build:\n\n runs-on: ubuntu-latest\n\n steps:\n - uses: actions/checkout@v1\n "
},
{
"path": ".gitignore",
"chars": 124,
"preview": "*.iml\n.gradle\n/local.properties\n/.idea/workspace.xml\n/.idea/libraries\n.DS_Store\n/build\n/captures\n.externalNativeBuild\n.i"
},
{
"path": "LICENSE",
"chars": 10894,
"preview": "\n Original work Copyright (c) 2005-2008, The Android Open Source Project\n Modified work Copyright (c) 2013, rovo89 a"
},
{
"path": "README.md",
"chars": 4924,
"preview": "[ ](https://bintray.com/twsxtd/maven/"
},
{
"path": "README_cn.md",
"chars": 3161,
"preview": "## 简介\n\nEpic 是一个在虚拟机层面、以 Java Method 为粒度的 **运行时** AOP Hook 框架。简单来说,Epic 就是 ART 上的 [Dexposed](https://github.com/alibaba/d"
},
{
"path": "app/.gitignore",
"chars": 7,
"preview": "/build\n"
},
{
"path": "app/build.gradle",
"chars": 939,
"preview": "apply plugin: 'com.android.application'\n\nandroid {\n compileSdkVersion 30\n defaultConfig {\n applicationId \"m"
},
{
"path": "app/proguard-rules.pro",
"chars": 935,
"preview": "# Add project specific ProGuard rules here.\n# By default, the flags in this file are appended to flags specified\n# in /U"
},
{
"path": "app/src/androidTest/java/me/weishu/epic/ExampleInstrumentedTest.java",
"chars": 837,
"preview": "//package me.weishu.epic;\n//\n//import android.content.Context;\n//import android.support.test.InstrumentationRegistry;\n//"
},
{
"path": "app/src/main/AndroidManifest.xml",
"chars": 777,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n package="
},
{
"path": "app/src/main/java/me/weishu/epic/samples/MainActivity.java",
"chars": 4249,
"preview": "package me.weishu.epic.samples;\n\nimport android.app.Activity;\nimport android.os.Bundle;\nimport android.util.Log;\nimport "
},
{
"path": "app/src/main/java/me/weishu/epic/samples/MainApplication.java",
"chars": 447,
"preview": "package me.weishu.epic.samples;\n\nimport android.app.Application;\nimport android.content.Context;\n\n/**\n * Created by weis"
},
{
"path": "app/src/main/java/me/weishu/epic/samples/tests/CallingConventationTest.java",
"chars": 698,
"preview": "package me.weishu.epic.samples.tests;\n\nimport me.weishu.epic.samples.tests.arguments.ArgumentTarget;\n\n/**\n * Created by "
},
{
"path": "app/src/main/java/me/weishu/epic/samples/tests/LogMethodHook.java",
"chars": 1238,
"preview": "package me.weishu.epic.samples.tests;\n\nimport android.util.Log;\n\nimport java.util.Arrays;\n\nimport de.robv.android.xposed"
},
{
"path": "app/src/main/java/me/weishu/epic/samples/tests/TestCase.java",
"chars": 890,
"preview": "package me.weishu.epic.samples.tests;\n\nimport android.util.Log;\nimport android.widget.Toast;\n\nimport me.weishu.epic.samp"
},
{
"path": "app/src/main/java/me/weishu/epic/samples/tests/TestManager.java",
"chars": 8252,
"preview": "package me.weishu.epic.samples.tests;\n\nimport android.os.Build;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimpo"
},
{
"path": "app/src/main/java/me/weishu/epic/samples/tests/TestSuite.java",
"chars": 511,
"preview": "package me.weishu.epic.samples.tests;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\n/**\n * Created by weishu on 1"
},
{
"path": "app/src/main/java/me/weishu/epic/samples/tests/arguments/AbsArgStaticCase.java",
"chars": 3708,
"preview": "package me.weishu.epic.samples.tests.arguments;\n\nimport android.util.Log;\n\nimport java.lang.reflect.Method;\nimport java."
},
{
"path": "app/src/main/java/me/weishu/epic/samples/tests/arguments/ArgStatic0.java",
"chars": 1173,
"preview": "package me.weishu.epic.samples.tests.arguments;\n\nimport de.robv.android.xposed.DexposedBridge;\nimport de.robv.android.xp"
},
{
"path": "app/src/main/java/me/weishu/epic/samples/tests/arguments/ArgStatic4.java",
"chars": 256,
"preview": "package me.weishu.epic.samples.tests.arguments;\n\n/**\n * @author weishu\n * @date 17/11/14.\n */\n\npublic class ArgStatic4 e"
},
{
"path": "app/src/main/java/me/weishu/epic/samples/tests/arguments/ArgStatic44.java",
"chars": 273,
"preview": "package me.weishu.epic.samples.tests.arguments;\n\n/**\n * @author weishu\n * @date 17/11/14.\n */\n\npublic class ArgStatic44 "
},
{
"path": "app/src/main/java/me/weishu/epic/samples/tests/arguments/ArgStatic444.java",
"chars": 405,
"preview": "package me.weishu.epic.samples.tests.arguments;\n\nimport android.util.Log;\n\nimport java.util.Arrays;\n\n/**\n * Created by w"
},
{
"path": "app/src/main/java/me/weishu/epic/samples/tests/arguments/ArgStatic4444.java",
"chars": 297,
"preview": "package me.weishu.epic.samples.tests.arguments;\n\n\n/**\n * Created by weishu on 17/11/14.\n */\npublic class ArgStatic4444 e"
},
{
"path": "app/src/main/java/me/weishu/epic/samples/tests/arguments/ArgStatic4448.java",
"chars": 293,
"preview": "package me.weishu.epic.samples.tests.arguments;\n\n\n/**\n * Created by weishu on 17/11/14.\n */\npublic class ArgStatic4448 e"
},
{
"path": "app/src/main/java/me/weishu/epic/samples/tests/arguments/ArgStatic448.java",
"chars": 280,
"preview": "package me.weishu.epic.samples.tests.arguments;\n\n/**\n * Created by weishu on 17/11/14.\n */\n\npublic class ArgStatic448 ex"
},
{
"path": "app/src/main/java/me/weishu/epic/samples/tests/arguments/ArgStatic4484.java",
"chars": 293,
"preview": "package me.weishu.epic.samples.tests.arguments;\n\n\n/**\n * Created by weishu on 17/11/14.\n */\npublic class ArgStatic4484 e"
},
{
"path": "app/src/main/java/me/weishu/epic/samples/tests/arguments/ArgStatic4488.java",
"chars": 287,
"preview": "package me.weishu.epic.samples.tests.arguments;\n\n\n/**\n * Created by weishu on 17/11/14.\n */\npublic class ArgStatic4488 e"
},
{
"path": "app/src/main/java/me/weishu/epic/samples/tests/arguments/ArgStatic48.java",
"chars": 267,
"preview": "package me.weishu.epic.samples.tests.arguments;\n\n/**\n * @author weishu\n * @date 17/11/14.\n */\n\npublic class ArgStatic48 "
},
{
"path": "app/src/main/java/me/weishu/epic/samples/tests/arguments/ArgStatic484.java",
"chars": 279,
"preview": "package me.weishu.epic.samples.tests.arguments;\n\n/**\n * Created by weishu on 17/11/14.\n */\n\npublic class ArgStatic484 ex"
},
{
"path": "app/src/main/java/me/weishu/epic/samples/tests/arguments/ArgStatic4844.java",
"chars": 293,
"preview": "package me.weishu.epic.samples.tests.arguments;\n\n\n/**\n * Created by weishu on 17/11/14.\n */\npublic class ArgStatic4844 e"
},
{
"path": "app/src/main/java/me/weishu/epic/samples/tests/arguments/ArgStatic4848.java",
"chars": 287,
"preview": "package me.weishu.epic.samples.tests.arguments;\n\n\n/**\n * Created by weishu on 17/11/14.\n */\npublic class ArgStatic4848 e"
},
{
"path": "app/src/main/java/me/weishu/epic/samples/tests/arguments/ArgStatic488.java",
"chars": 273,
"preview": "package me.weishu.epic.samples.tests.arguments;\n\n/**\n * Created by weishu on 17/11/14.\n */\n\npublic class ArgStatic488 ex"
},
{
"path": "app/src/main/java/me/weishu/epic/samples/tests/arguments/ArgStatic4884.java",
"chars": 287,
"preview": "package me.weishu.epic.samples.tests.arguments;\n\n\n/**\n * Created by weishu on 17/11/14.\n */\npublic class ArgStatic4884 e"
},
{
"path": "app/src/main/java/me/weishu/epic/samples/tests/arguments/ArgStatic4888.java",
"chars": 282,
"preview": "package me.weishu.epic.samples.tests.arguments;\n\n\n/**\n * Created by weishu on 17/11/14.\n */\npublic class ArgStatic4888 e"
},
{
"path": "app/src/main/java/me/weishu/epic/samples/tests/arguments/ArgStatic8.java",
"chars": 251,
"preview": "package me.weishu.epic.samples.tests.arguments;\n\n/**\n * @author weishu\n * @date 17/11/14.\n */\n\npublic class ArgStatic8 e"
},
{
"path": "app/src/main/java/me/weishu/epic/samples/tests/arguments/ArgStatic84.java",
"chars": 266,
"preview": "package me.weishu.epic.samples.tests.arguments;\n\n/**\n * @author weishu\n * @date 17/11/14.\n */\n\npublic class ArgStatic84 "
},
{
"path": "app/src/main/java/me/weishu/epic/samples/tests/arguments/ArgStatic844.java",
"chars": 279,
"preview": "package me.weishu.epic.samples.tests.arguments;\n\n/**\n * Created by weishu on 17/11/14.\n */\n\npublic class ArgStatic844 ex"
},
{
"path": "app/src/main/java/me/weishu/epic/samples/tests/arguments/ArgStatic8444.java",
"chars": 292,
"preview": "package me.weishu.epic.samples.tests.arguments;\n\n\n/**\n * Created by weishu on 17/11/14.\n */\npublic class ArgStatic8444 e"
},
{
"path": "app/src/main/java/me/weishu/epic/samples/tests/arguments/ArgStatic8448.java",
"chars": 287,
"preview": "package me.weishu.epic.samples.tests.arguments;\n\n\n/**\n * Created by weishu on 17/11/14.\n */\npublic class ArgStatic8448 e"
},
{
"path": "app/src/main/java/me/weishu/epic/samples/tests/arguments/ArgStatic848.java",
"chars": 273,
"preview": "package me.weishu.epic.samples.tests.arguments;\n\n/**\n * Created by weishu on 17/11/14.\n */\n\npublic class ArgStatic848 ex"
},
{
"path": "app/src/main/java/me/weishu/epic/samples/tests/arguments/ArgStatic8484.java",
"chars": 287,
"preview": "package me.weishu.epic.samples.tests.arguments;\n\n\n/**\n * Created by weishu on 17/11/14.\n */\npublic class ArgStatic8484 e"
},
{
"path": "app/src/main/java/me/weishu/epic/samples/tests/arguments/ArgStatic8488.java",
"chars": 282,
"preview": "package me.weishu.epic.samples.tests.arguments;\n\n\n/**\n * Created by weishu on 17/11/14.\n */\npublic class ArgStatic8488 e"
},
{
"path": "app/src/main/java/me/weishu/epic/samples/tests/arguments/ArgStatic88.java",
"chars": 291,
"preview": "package me.weishu.epic.samples.tests.arguments;\n\n/**\n * @author weishu\n * @date 17/11/14.\n */\n\npublic class ArgStatic88 "
},
{
"path": "app/src/main/java/me/weishu/epic/samples/tests/arguments/ArgStatic884.java",
"chars": 273,
"preview": "package me.weishu.epic.samples.tests.arguments;\n\n\n/**\n * Created by weishu on 17/11/14.\n */\npublic class ArgStatic884 ex"
},
{
"path": "app/src/main/java/me/weishu/epic/samples/tests/arguments/ArgStatic8844.java",
"chars": 287,
"preview": "package me.weishu.epic.samples.tests.arguments;\n\n\n/**\n * Created by weishu on 17/11/14.\n */\npublic class ArgStatic8844 e"
},
{
"path": "app/src/main/java/me/weishu/epic/samples/tests/arguments/ArgStatic8848.java",
"chars": 282,
"preview": "package me.weishu.epic.samples.tests.arguments;\n\n\n/**\n * Created by weishu on 17/11/14.\n */\npublic class ArgStatic8848 e"
},
{
"path": "app/src/main/java/me/weishu/epic/samples/tests/arguments/ArgStatic888.java",
"chars": 267,
"preview": "package me.weishu.epic.samples.tests.arguments;\n\n\n/**\n * Created by weishu on 17/11/14.\n */\npublic class ArgStatic888 ex"
},
{
"path": "app/src/main/java/me/weishu/epic/samples/tests/arguments/ArgStatic8884.java",
"chars": 282,
"preview": "package me.weishu.epic.samples.tests.arguments;\n\n\n/**\n * Created by weishu on 17/11/14.\n */\npublic class ArgStatic8884 e"
},
{
"path": "app/src/main/java/me/weishu/epic/samples/tests/arguments/ArgStatic8888.java",
"chars": 277,
"preview": "package me.weishu.epic.samples.tests.arguments;\n\n\n/**\n * Created by weishu on 17/11/14.\n */\npublic class ArgStatic8888 e"
},
{
"path": "app/src/main/java/me/weishu/epic/samples/tests/arguments/ArgumentTarget.java",
"chars": 8854,
"preview": "package me.weishu.epic.samples.tests.arguments;\n\nimport android.util.Log;\n\n/**\n * @author weishu\n * @date 17/11/13.\n */\n"
},
{
"path": "app/src/main/java/me/weishu/epic/samples/tests/custom/Case.java",
"chars": 170,
"preview": "package me.weishu.epic.samples.tests.custom;\n\n/**\n * Created by weishu on 17/11/6.\n */\n\npublic interface Case {\n void"
},
{
"path": "app/src/main/java/me/weishu/epic/samples/tests/custom/Case1.java",
"chars": 2232,
"preview": "package me.weishu.epic.samples.tests.custom;\n\nimport android.os.SystemClock;\nimport android.util.Log;\n\nimport java.lang."
},
{
"path": "app/src/main/java/me/weishu/epic/samples/tests/custom/Case10_Default_Constructor.java",
"chars": 974,
"preview": "package me.weishu.epic.samples.tests.custom;\n\nimport android.util.Log;\n\nimport java.lang.reflect.Constructor;\n\nimport de"
},
{
"path": "app/src/main/java/me/weishu/epic/samples/tests/custom/Case11_SuspendAll.java",
"chars": 1508,
"preview": "package me.weishu.epic.samples.tests.custom;\n\nimport android.os.Build;\nimport android.os.SystemClock;\nimport android.uti"
},
{
"path": "app/src/main/java/me/weishu/epic/samples/tests/custom/Case12_MultiCallback.java",
"chars": 2553,
"preview": "package me.weishu.epic.samples.tests.custom;\n\nimport android.util.Log;\n\nimport de.robv.android.xposed.DexposedBridge;\nim"
},
{
"path": "app/src/main/java/me/weishu/epic/samples/tests/custom/Case13_FastNative.java",
"chars": 675,
"preview": "package me.weishu.epic.samples.tests.custom;\n\nimport android.util.Log;\n\nimport java.lang.reflect.Method;\n\nimport de.robv"
},
{
"path": "app/src/main/java/me/weishu/epic/samples/tests/custom/Case14_GC.java",
"chars": 625,
"preview": "package me.weishu.epic.samples.tests.custom;\n\nimport de.robv.android.xposed.DexposedBridge;\n\nimport me.weishu.epic.sampl"
},
{
"path": "app/src/main/java/me/weishu/epic/samples/tests/custom/Case15_StopJit.java",
"chars": 402,
"preview": "package me.weishu.epic.samples.tests.custom;\n\nimport me.weishu.epic.art.EpicNative;\n\n/**\n * Created by weishu on 17/12/1"
},
{
"path": "app/src/main/java/me/weishu/epic/samples/tests/custom/Case16_SameEntry.java",
"chars": 2653,
"preview": "package me.weishu.epic.samples.tests.custom;\n\nimport android.util.Log;\n\nimport com.taobao.android.dexposed.utility.Debug"
},
{
"path": "app/src/main/java/me/weishu/epic/samples/tests/custom/Case17_SameMethod.java",
"chars": 1798,
"preview": "package me.weishu.epic.samples.tests.custom;\n\nimport android.util.Log;\n\nimport de.robv.android.xposed.DexposedBridge;\nim"
},
{
"path": "app/src/main/java/me/weishu/epic/samples/tests/custom/Case18_returnConst.java",
"chars": 1286,
"preview": "package me.weishu.epic.samples.tests.custom;\n\nimport android.util.Log;\n\nimport java.util.Arrays;\n\nimport de.robv.android"
},
{
"path": "app/src/main/java/me/weishu/epic/samples/tests/custom/Case2.java",
"chars": 1644,
"preview": "package me.weishu.epic.samples.tests.custom;\n\n/**\n * Created by weishu on 17/11/6.\n */\n\npublic class Case2 implements Ca"
},
{
"path": "app/src/main/java/me/weishu/epic/samples/tests/custom/Case3.java",
"chars": 1072,
"preview": "package me.weishu.epic.samples.tests.custom;\n\nimport android.util.Log;\n\nimport de.robv.android.xposed.DexposedBridge;\nim"
},
{
"path": "app/src/main/java/me/weishu/epic/samples/tests/custom/Case4.java",
"chars": 1397,
"preview": "package me.weishu.epic.samples.tests.custom;\n\nimport android.text.TextUtils;\nimport android.util.Log;\n\nimport de.robv.an"
},
{
"path": "app/src/main/java/me/weishu/epic/samples/tests/custom/Case5.java",
"chars": 1954,
"preview": "package me.weishu.epic.samples.tests.custom;\n\nimport android.util.Log;\nimport android.widget.TextView;\n\nimport com.taoba"
},
{
"path": "app/src/main/java/me/weishu/epic/samples/tests/custom/Case6.java",
"chars": 2223,
"preview": "package me.weishu.epic.samples.tests.custom;\n\nimport android.os.SystemClock;\nimport android.util.Log;\n\nimport com.taobao"
},
{
"path": "app/src/main/java/me/weishu/epic/samples/tests/custom/Case7.java",
"chars": 958,
"preview": "package me.weishu.epic.samples.tests.custom;\n\nimport android.util.Log;\n\nimport java.util.Arrays;\n\nimport de.robv.android"
},
{
"path": "app/src/main/java/me/weishu/epic/samples/tests/custom/Case8_Activity_onCreate.java",
"chars": 1138,
"preview": "package me.weishu.epic.samples.tests.custom;\n\nimport android.os.Bundle;\nimport android.util.Log;\n\nimport de.robv.android"
},
{
"path": "app/src/main/java/me/weishu/epic/samples/tests/custom/Case9_ThreadMonitor.java",
"chars": 2889,
"preview": "package me.weishu.epic.samples.tests.custom;\n\nimport android.util.Log;\n\nimport java.util.concurrent.ExecutorService;\nimp"
},
{
"path": "app/src/main/java/me/weishu/epic/samples/tests/custom/CaseManager.java",
"chars": 966,
"preview": "package me.weishu.epic.samples.tests.custom;\n\nimport java.util.Map;\nimport java.util.Set;\nimport java.util.concurrent.Co"
},
{
"path": "app/src/main/java/me/weishu/epic/samples/tests/custom/Target.java",
"chars": 2229,
"preview": "package me.weishu.epic.samples.tests.custom;\n\nimport android.os.SystemClock;\nimport android.util.Log;\n\nimport java.lang."
},
{
"path": "app/src/main/java/me/weishu/epic/samples/tests/invoketype/InvokeConstructor.java",
"chars": 1181,
"preview": "package me.weishu.epic.samples.tests.invoketype;\n\nimport de.robv.android.xposed.DexposedBridge;\nimport de.robv.android.x"
},
{
"path": "app/src/main/java/me/weishu/epic/samples/tests/invoketype/InvokeTypeTarget.java",
"chars": 128,
"preview": "package me.weishu.epic.samples.tests.invoketype;\n\n/**\n * Created by weishu on 17/11/14.\n */\n\npublic class InvokeTypeTarg"
},
{
"path": "app/src/main/java/me/weishu/epic/samples/tests/returntype/BooleanType.java",
"chars": 981,
"preview": "package me.weishu.epic.samples.tests.returntype;\n\nimport de.robv.android.xposed.DexposedBridge;\n\nimport me.weishu.epic.s"
},
{
"path": "app/src/main/java/me/weishu/epic/samples/tests/returntype/ByteType.java",
"chars": 995,
"preview": "package me.weishu.epic.samples.tests.returntype;\n\nimport de.robv.android.xposed.DexposedBridge;\n\nimport me.weishu.epic.s"
},
{
"path": "app/src/main/java/me/weishu/epic/samples/tests/returntype/CharType.java",
"chars": 967,
"preview": "package me.weishu.epic.samples.tests.returntype;\n\nimport de.robv.android.xposed.DexposedBridge;\n\nimport me.weishu.epic.s"
},
{
"path": "app/src/main/java/me/weishu/epic/samples/tests/returntype/CustomType.java",
"chars": 1023,
"preview": "package me.weishu.epic.samples.tests.returntype;\n\nimport de.robv.android.xposed.DexposedBridge;\n\nimport me.weishu.epic.s"
},
{
"path": "app/src/main/java/me/weishu/epic/samples/tests/returntype/DoubleType.java",
"chars": 978,
"preview": "package me.weishu.epic.samples.tests.returntype;\n\nimport de.robv.android.xposed.DexposedBridge;\n\nimport me.weishu.epic.s"
},
{
"path": "app/src/main/java/me/weishu/epic/samples/tests/returntype/FloatType.java",
"chars": 966,
"preview": "package me.weishu.epic.samples.tests.returntype;\n\nimport de.robv.android.xposed.DexposedBridge;\n\nimport me.weishu.epic.s"
},
{
"path": "app/src/main/java/me/weishu/epic/samples/tests/returntype/IntType.java",
"chars": 982,
"preview": "package me.weishu.epic.samples.tests.returntype;\n\nimport de.robv.android.xposed.DexposedBridge;\n\nimport me.weishu.epic.s"
},
{
"path": "app/src/main/java/me/weishu/epic/samples/tests/returntype/LongType.java",
"chars": 966,
"preview": "package me.weishu.epic.samples.tests.returntype;\n\nimport de.robv.android.xposed.DexposedBridge;\n\nimport me.weishu.epic.s"
},
{
"path": "app/src/main/java/me/weishu/epic/samples/tests/returntype/ReturnTypeTarget.java",
"chars": 1679,
"preview": "package me.weishu.epic.samples.tests.returntype;\n\nimport android.util.Log;\n\n/**\n * Created by weishu on 17/11/13.\n */\n\np"
},
{
"path": "app/src/main/java/me/weishu/epic/samples/tests/returntype/ShortType.java",
"chars": 974,
"preview": "package me.weishu.epic.samples.tests.returntype;\n\nimport de.robv.android.xposed.DexposedBridge;\n\nimport me.weishu.epic.s"
},
{
"path": "app/src/main/java/me/weishu/epic/samples/tests/returntype/StringArrayType.java",
"chars": 1040,
"preview": "package me.weishu.epic.samples.tests.returntype;\n\nimport de.robv.android.xposed.DexposedBridge;\n\nimport me.weishu.epic.s"
},
{
"path": "app/src/main/java/me/weishu/epic/samples/tests/returntype/StringType.java",
"chars": 979,
"preview": "package me.weishu.epic.samples.tests.returntype;\n\nimport de.robv.android.xposed.DexposedBridge;\n\nimport me.weishu.epic.s"
},
{
"path": "app/src/main/java/me/weishu/epic/samples/tests/returntype/VoidType.java",
"chars": 1254,
"preview": "package me.weishu.epic.samples.tests.returntype;\n\nimport android.util.Log;\n\nimport de.robv.android.xposed.DexposedBridge"
},
{
"path": "app/src/main/res/layout/activity_main.xml",
"chars": 652,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n xmln"
},
{
"path": "app/src/main/res/layout/child_layout.xml",
"chars": 1032,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n an"
},
{
"path": "app/src/main/res/layout/parent_layout.xml",
"chars": 890,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n an"
},
{
"path": "app/src/main/res/values/colors.xml",
"chars": 208,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n <color name=\"colorPrimary\">#3F51B5</color>\n <color name=\"color"
},
{
"path": "app/src/main/res/values/strings.xml",
"chars": 67,
"preview": "<resources>\n <string name=\"app_name\">epic</string>\n</resources>\n"
},
{
"path": "app/src/main/res/values/styles.xml",
"chars": 197,
"preview": "<resources>\n\n <!-- Base application theme. -->\n <style name=\"AppTheme\" parent=\"android:Theme.Holo.Light.DarkAction"
},
{
"path": "app/src/test/java/me/weishu/epic/ExampleUnitTest.java",
"chars": 426,
"preview": "//package me.weishu.epic;\n//\n//import org.junit.Test;\n//\n//import static org.junit.Assert.*;\n//\n///**\n// * Example local"
},
{
"path": "build.gradle",
"chars": 888,
"preview": "// Top-level build file where you can add configuration options common to all sub-projects/modules.\n\nbuildscript {\n r"
},
{
"path": "gradle/wrapper/gradle-wrapper.properties",
"chars": 232,
"preview": "#Tue Nov 07 13:44:26 CST 2017\ndistributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\nzipStoreBase=GRADLE_USER_"
},
{
"path": "gradle.properties",
"chars": 723,
"preview": "## Project-wide Gradle settings.\n#\n# For more details on how to configure your build environment visit\n# http://www.grad"
},
{
"path": "gradlew",
"chars": 4971,
"preview": "#!/usr/bin/env bash\n\n##############################################################################\n##\n## Gradle start "
},
{
"path": "gradlew.bat",
"chars": 2314,
"preview": "@if \"%DEBUG%\" == \"\" @echo off\n@rem ##########################################################################\n@rem\n@rem "
},
{
"path": "library/.gitignore",
"chars": 7,
"preview": "/build\n"
},
{
"path": "library/CMakeCache.txt",
"chars": 14967,
"preview": "# This is the CMakeCache file.\n# For build in directory: /Users/weishu/dev/space/arthook/epic/library\n# It was generated"
},
{
"path": "library/build.gradle",
"chars": 1488,
"preview": "apply plugin: 'com.android.library'\n\nandroid {\n compileSdkVersion 31\n\n defaultConfig {\n minSdkVersion 21\n "
},
{
"path": "library/proguard-rules.pro",
"chars": 1455,
"preview": "# Add project specific ProGuard rules here.\n# By default, the flags in this file are appended to flags specified\n# in /U"
},
{
"path": "library/src/main/AndroidManifest.xml",
"chars": 335,
"preview": "<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n xmlns:tools=\"http://schemas.android.com/tools\"\n"
},
{
"path": "library/src/main/cpp/.gitignore",
"chars": 7,
"preview": "build/\n"
},
{
"path": "library/src/main/cpp/CMakeLists.txt",
"chars": 1734,
"preview": "# For more information about using CMake with Android Studio, read the\n# documentation: https://d.android.com/studio/pro"
},
{
"path": "library/src/main/cpp/art.cpp",
"chars": 2863,
"preview": "/*\n * Copyright (c) 2017, weishu\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "library/src/main/cpp/art.h",
"chars": 4804,
"preview": "/*\n * Copyright (c) 2017, weishu\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "library/src/main/cpp/build_with_cmake",
"chars": 156,
"preview": "#! /bin/sh\ncmake -DCMAKE_TOOLCHAIN_FILE=$ANDROID_SDK/ndk-bundle/build/cmake/android.toolchain.cmake -DANDROID_TOOLCHAIN="
},
{
"path": "library/src/main/cpp/epic.cpp",
"chars": 17897,
"preview": "/*\n * Original Copyright 2014-2015 Marvin Wißfeld\n * Modified work Copyright (c) 2017, weishu\n *\n * Licensed under the A"
},
{
"path": "library/src/main/cpp/fake_dlfcn.cpp",
"chars": 9541,
"preview": "// Copyright (c) 2016 avs333\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n//\t\tof t"
},
{
"path": "library/src/main/cpp/fake_dlfcn.h",
"chars": 1426,
"preview": "// Copyright (c) 2016 avs333\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n//\t\tof t"
},
{
"path": "library/src/main/java/com/taobao/android/dexposed/ClassUtils.java",
"chars": 24105,
"preview": "/*\n * Original work Copyright (c) 2005-2008, The Android Open Source Project\n * Modified work Copyright (c) 2013, rovo89"
},
{
"path": "library/src/main/java/com/taobao/android/dexposed/DeviceCheck.java",
"chars": 4986,
"preview": "/*\n * Original work Copyright (c) 2005-2008, The Android Open Source Project\n * Modified work Copyright (c) 2013, rovo89"
},
{
"path": "library/src/main/java/com/taobao/android/dexposed/utility/Debug.java",
"chars": 3568,
"preview": "/*\n * Original work Copyright (c) 2014-2015, Marvin Wißfeld\n * Modified work Copyright (c) 2016, Alibaba Mobile Infrastr"
},
{
"path": "library/src/main/java/com/taobao/android/dexposed/utility/Logger.java",
"chars": 872,
"preview": "package com.taobao.android.dexposed.utility;\n\nimport android.util.Log;\n\n/**\n * Created by weishu on 17/11/10.\n */\npublic"
},
{
"path": "library/src/main/java/com/taobao/android/dexposed/utility/NeverCalled.java",
"chars": 320,
"preview": "package com.taobao.android.dexposed.utility;\n\nimport android.util.Log;\n\n/**\n * This Class is used for get the art_quick_"
},
{
"path": "library/src/main/java/com/taobao/android/dexposed/utility/NougatPolicy.java",
"chars": 2782,
"preview": "package com.taobao.android.dexposed.utility;\n\nimport android.content.Context;\nimport android.os.SystemClock;\nimport andr"
},
{
"path": "library/src/main/java/com/taobao/android/dexposed/utility/Platform.java",
"chars": 3449,
"preview": "/*\n * Original work Copyright (c) 2016, Lody\n * Modified work Copyright (c) 2016, Alibaba Mobile Infrastructure (Android"
},
{
"path": "library/src/main/java/com/taobao/android/dexposed/utility/Runtime.java",
"chars": 2410,
"preview": "/*\n * Original work Copyright (c) 2016, Lody\n * Modified work Copyright (c) 2016, Alibaba Mobile Infrastructure (Android"
},
{
"path": "library/src/main/java/com/taobao/android/dexposed/utility/Unsafe.java",
"chars": 5146,
"preview": "/*\n * Copyright 2014-2015 Marvin Wißfeld\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you ma"
},
{
"path": "library/src/main/java/de/robv/android/xposed/DexposedBridge.java",
"chars": 18217,
"preview": "/*\n * Original work Copyright (c) 2005-2008, The Android Open Source Project\n * Modified work Copyright (c) 2013, rovo89"
},
{
"path": "library/src/main/java/me/weishu/epic/art/Epic.java",
"chars": 8139,
"preview": "/*\n * Copyright (c) 2017, weishu\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not us"
},
{
"path": "library/src/main/java/me/weishu/epic/art/EpicNative.java",
"chars": 5738,
"preview": "/*\n * Copyright (c) 2017, weishu twsxtd@gmail.com\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n"
},
{
"path": "library/src/main/java/me/weishu/epic/art/Trampoline.java",
"chars": 6108,
"preview": "/*\n * Copyright (c) 2017, weishu twsxtd@gmail.com\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n"
},
{
"path": "library/src/main/java/me/weishu/epic/art/arch/Arm64.java",
"chars": 3805,
"preview": "/*\n * Copyright (c) 2017, weishu twsxtd@gmail.com\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n"
},
{
"path": "library/src/main/java/me/weishu/epic/art/arch/Arm64_2.java",
"chars": 4148,
"preview": "/*\n * Copyright (c) 2017, weishu twsxtd@gmail.com\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n"
},
{
"path": "library/src/main/java/me/weishu/epic/art/arch/ShellCode.java",
"chars": 2086,
"preview": "/*\n * Copyright (c) 2017, weishu twsxtd@gmail.com\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n"
},
{
"path": "library/src/main/java/me/weishu/epic/art/arch/Thumb2.java",
"chars": 5373,
"preview": "/*\n * Copyright (c) 2017, weishu twsxtd@gmail.com\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n"
},
{
"path": "library/src/main/java/me/weishu/epic/art/entry/Entry.java",
"chars": 18202,
"preview": "/*\n * Copyright (c) 2017, weishu twsxtd@gmail.com\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n"
},
{
"path": "library/src/main/java/me/weishu/epic/art/entry/Entry64.java",
"chars": 12785,
"preview": "/*\n * Copyright (c) 2017, weishu twsxtd@gmail.com\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n"
},
{
"path": "library/src/main/java/me/weishu/epic/art/entry/Entry64_2.java",
"chars": 21385,
"preview": "/*\n * Copyright (c) 2017, weishu twsxtd@gmail.com\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n"
},
{
"path": "library/src/main/java/me/weishu/epic/art/method/ArtMethod.java",
"chars": 17401,
"preview": "/*\n * Copyright (c) 2017, weishu twsxtd@gmail.com\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n"
},
{
"path": "library/src/main/java/me/weishu/epic/art/method/Offset.java",
"chars": 8743,
"preview": "/*\n * Copyright (c) 2017, weishu twsxtd@gmail.com\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n"
},
{
"path": "library/src/main/res/values/strings.xml",
"chars": 67,
"preview": "<resources>\n <string name=\"app_name\">epic</string>\n</resources>\n"
},
{
"path": "settings.gradle",
"chars": 27,
"preview": "include ':app', ':library'\n"
}
]
// ... and 1 more files (download for full content)
About this extraction
This page contains the full source code of the tiann/epic GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 137 files (349.2 KB), approximately 92.7k tokens, and a symbol index with 732 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.