Add vpn hide xposed module

This commit is contained in:
世界
2026-01-07 20:31:27 +08:00
parent 8a8686b3df
commit cd83cbfe9e
152 changed files with 12994 additions and 2782 deletions

201
third_party/libxposed-api/LICENSE vendored Normal file
View File

@@ -0,0 +1,201 @@
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
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
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.

View File

@@ -0,0 +1,26 @@
plugins {
id("com.android.library")
}
android {
namespace = "io.github.libxposed.api"
compileSdk = 36
defaultConfig {
minSdk = 21
}
buildFeatures {
androidResources = false
buildConfig = false
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
}
dependencies {
compileOnly("androidx.annotation:annotation:1.7.1")
}

View File

@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest />

View File

@@ -0,0 +1,525 @@
package io.github.libxposed.api;
import android.content.SharedPreferences;
import android.content.pm.ApplicationInfo;
import android.os.ParcelFileDescriptor;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.nio.ByteBuffer;
import io.github.libxposed.api.errors.HookFailedError;
import io.github.libxposed.api.utils.DexParser;
/**
* Xposed interface for modules to operate on application processes.
*/
@SuppressWarnings("unused")
public interface XposedInterface {
/**
* SDK API version.
*/
int API = 100;
/**
* Indicates that the framework is running as root.
*/
int FRAMEWORK_PRIVILEGE_ROOT = 0;
/**
* Indicates that the framework is running in a container with a fake system_server.
*/
int FRAMEWORK_PRIVILEGE_CONTAINER = 1;
/**
* Indicates that the framework is running as a different app, which may have at most shell permission.
*/
int FRAMEWORK_PRIVILEGE_APP = 2;
/**
* Indicates that the framework is embedded in the hooked app,
* which means {@link #getRemotePreferences} will be null and remote file is unsupported.
*/
int FRAMEWORK_PRIVILEGE_EMBEDDED = 3;
/**
* The default hook priority.
*/
int PRIORITY_DEFAULT = 50;
/**
* Execute the hook callback late.
*/
int PRIORITY_LOWEST = -10000;
/**
* Execute the hook callback early.
*/
int PRIORITY_HIGHEST = 10000;
/**
* Contextual interface for before invocation callbacks.
*/
interface BeforeHookCallback {
/**
* Gets the method / constructor to be hooked.
*/
@NonNull
Member getMember();
/**
* Gets the {@code this} object, or {@code null} if the method is static.
*/
@Nullable
Object getThisObject();
/**
* Gets the arguments passed to the method / constructor. You can modify the arguments.
*/
@NonNull
Object[] getArgs();
/**
* Sets the return value of the method and skip the invocation. If the procedure is a constructor,
* the {@code result} param will be ignored.
* Note that the after invocation callback will still be called.
*
* @param result The return value
*/
void returnAndSkip(@Nullable Object result);
/**
* Throw an exception from the method / constructor and skip the invocation.
* Note that the after invocation callback will still be called.
*
* @param throwable The exception to be thrown
*/
void throwAndSkip(@Nullable Throwable throwable);
}
/**
* Contextual interface for after invocation callbacks.
*/
interface AfterHookCallback {
/**
* Gets the method / constructor to be hooked.
*/
@NonNull
Member getMember();
/**
* Gets the {@code this} object, or {@code null} if the method is static.
*/
@Nullable
Object getThisObject();
/**
* Gets all arguments passed to the method / constructor.
*/
@NonNull
Object[] getArgs();
/**
* Gets the return value of the method or the before invocation callback. If the procedure is a
* constructor, a void method or an exception was thrown, the return value will be {@code null}.
*/
@Nullable
Object getResult();
/**
* Gets the exception thrown by the method / constructor or the before invocation callback. If the
* procedure call was successful, the return value will be {@code null}.
*/
@Nullable
Throwable getThrowable();
/**
* Gets whether the invocation was skipped by the before invocation callback.
*/
boolean isSkipped();
/**
* Sets the return value of the method and skip the invocation. If the procedure is a constructor,
* the {@code result} param will be ignored.
*
* @param result The return value
*/
void setResult(@Nullable Object result);
/**
* Sets the exception thrown by the method / constructor.
*
* @param throwable The exception to be thrown.
*/
void setThrowable(@Nullable Throwable throwable);
}
/**
* Interface for method / constructor hooking. Xposed modules should define their own hooker class
* and implement this interface. Normally, a hooker class corresponds to a method / constructor, but
* there could also be a single hooker class for all of them. By this way you can implement an interface
* like the old API.
*
* <p>
* Classes implementing this interface should should provide two public static methods named
* before and after for before invocation and after invocation respectively.
* </p>
*
* <p>
* The before invocation method should have the following signature:<br/>
* Param {@code callback}: The {@link BeforeHookCallback} of the procedure call.<br/>
* Return value: If you want to save contextual information of one procedure call between the before
* and after callback, it could be a self-defined class, otherwise it should be {@code void}.
* </p>
*
* <p>
* The after invocation method should have the following signature:<br/>
* Param {@code callback}: The {@link AfterHookCallback} of the procedure call.<br/>
* Param {@code context} (optional): The contextual object returned by the before invocation.
* </p>
*
* <p>Example usage:</p>
*
* <pre>{@code
* public class ExampleHooker implements Hooker {
*
* public static void before(@NonNull BeforeHookCallback callback) {
* // Pre-hooking logic goes here
* }
*
* public static void after(@NonNull AfterHookCallback callback) {
* // Post-hooking logic goes here
* }
* }
*
* public class ExampleHookerWithContext implements Hooker {
*
* public static MyContext before(@NonNull BeforeHookCallback callback) {
* // Pre-hooking logic goes here
* return new MyContext();
* }
*
* public static void after(@NonNull AfterHookCallback callback, MyContext context) {
* // Post-hooking logic goes here
* }
* }
* }</pre>
*/
interface Hooker {
}
/**
* Interface for canceling a hook.
*
* @param <T> {@link Method} or {@link Constructor}
*/
interface MethodUnhooker<T> {
/**
* Gets the method or constructor being hooked.
*/
@NonNull
T getOrigin();
/**
* Cancels the hook. The behavior of calling this method multiple times is undefined.
*/
void unhook();
}
/**
* Gets the Xposed framework name of current implementation.
*
* @return Framework name
*/
@NonNull
String getFrameworkName();
/**
* Gets the Xposed framework version of current implementation.
*
* @return Framework version
*/
@NonNull
String getFrameworkVersion();
/**
* Gets the Xposed framework version code of current implementation.
*
* @return Framework version code
*/
long getFrameworkVersionCode();
/**
* Gets the Xposed framework privilege of current implementation.
*
* @return Framework privilege
*/
int getFrameworkPrivilege();
/**
* Hook a method with default priority.
*
* @param origin The method to be hooked
* @param hooker The hooker class
* @return Unhooker for canceling the hook
* @throws IllegalArgumentException if origin is abstract, framework internal or {@link Method#invoke},
* or hooker is invalid
* @throws HookFailedError if hook fails due to framework internal error
*/
@NonNull
MethodUnhooker<Method> hook(@NonNull Method origin, @NonNull Class<? extends Hooker> hooker);
/**
* Hook the static initializer of a class with default priority.
* <p>
* Note: If the class is initialized, the hook will never be called.
* </p>
*
* @param origin The class to be hooked
* @param hooker The hooker class
* @return Unhooker for canceling the hook
* @throws IllegalArgumentException if class has no static initializer or hooker is invalid
* @throws HookFailedError if hook fails due to framework internal error
*/
@NonNull
<T> MethodUnhooker<Constructor<T>> hookClassInitializer(@NonNull Class<T> origin, @NonNull Class<? extends Hooker> hooker);
/**
* Hook the static initializer of a class with specified priority.
* <p>
* Note: If the class is initialized, the hook will never be called.
* </p>
*
* @param origin The class to be hooked
* @param priority The hook priority
* @param hooker The hooker class
* @return Unhooker for canceling the hook
* @throws IllegalArgumentException if class has no static initializer or hooker is invalid
* @throws HookFailedError if hook fails due to framework internal error
*/
@NonNull
<T> MethodUnhooker<Constructor<T>> hookClassInitializer(@NonNull Class<T> origin, int priority, @NonNull Class<? extends Hooker> hooker);
/**
* Hook a method with specified priority.
*
* @param origin The method to be hooked
* @param priority The hook priority
* @param hooker The hooker class
* @return Unhooker for canceling the hook
* @throws IllegalArgumentException if origin is abstract, framework internal or {@link Method#invoke},
* or hooker is invalid
* @throws HookFailedError if hook fails due to framework internal error
*/
@NonNull
MethodUnhooker<Method> hook(@NonNull Method origin, int priority, @NonNull Class<? extends Hooker> hooker);
/**
* Hook a constructor with default priority.
*
* @param <T> The type of the constructor
* @param origin The constructor to be hooked
* @param hooker The hooker class
* @return Unhooker for canceling the hook
* @throws IllegalArgumentException if origin is abstract, framework internal or {@link Method#invoke},
* or hooker is invalid
* @throws HookFailedError if hook fails due to framework internal error
*/
@NonNull
<T> MethodUnhooker<Constructor<T>> hook(@NonNull Constructor<T> origin, @NonNull Class<? extends Hooker> hooker);
/**
* Hook a constructor with specified priority.
*
* @param <T> The type of the constructor
* @param origin The constructor to be hooked
* @param priority The hook priority
* @param hooker The hooker class
* @return Unhooker for canceling the hook
* @throws IllegalArgumentException if origin is abstract, framework internal or {@link Method#invoke},
* or hooker is invalid
* @throws HookFailedError if hook fails due to framework internal error
*/
@NonNull
<T> MethodUnhooker<Constructor<T>> hook(@NonNull Constructor<T> origin, int priority, @NonNull Class<? extends Hooker> hooker);
/**
* Deoptimizes a method in case hooked callee is not called because of inline.
*
* <p>By deoptimizing the method, the method will back all callee without inlining.
* For example, when a short hooked method B is invoked by method A, the callback to B is not invoked
* after hooking, which may mean A has inlined B inside its method body. To force A to call the hooked B,
* you can deoptimize A and then your hook can take effect.</p>
*
* <p>Generally, you need to find all the callers of your hooked callee and that can be hardly achieve
* (but you can still search all callers by using {@link DexParser}). Use this method if you are sure
* the deoptimized callers are all you need. Otherwise, it would be better to change the hook point or
* to deoptimize the whole app manually (by simply reinstalling the app without uninstall).</p>
*
* @param method The method to deoptimize
* @return Indicate whether the deoptimizing succeed or not
*/
boolean deoptimize(@NonNull Method method);
/**
* Deoptimizes a constructor in case hooked callee is not called because of inline.
*
* @param <T> The type of the constructor
* @param constructor The constructor to deoptimize
* @return Indicate whether the deoptimizing succeed or not
* @see #deoptimize(Method)
*/
<T> boolean deoptimize(@NonNull Constructor<T> constructor);
/**
* Basically the same as {@link Method#invoke(Object, Object...)}, but calls the original method
* as it was before the interception by Xposed.
*
* @param method The method to be called
* @param thisObject For non-static calls, the {@code this} pointer, otherwise {@code null}
* @param args The arguments used for the method call
* @return The result returned from the invoked method
* @see Method#invoke(Object, Object...)
*/
@Nullable
Object invokeOrigin(@NonNull Method method, @Nullable Object thisObject, Object... args) throws InvocationTargetException, IllegalArgumentException, IllegalAccessException;
/**
* Basically the same as {@link Constructor#newInstance(Object...)}, but calls the original constructor
* as it was before the interception by Xposed.
*
* @param constructor The constructor to create and initialize a new instance
* @param thisObject The instance to be constructed
* @param args The arguments used for the construction
* @param <T> The type of the instance
* @see Constructor#newInstance(Object...)
*/
<T> void invokeOrigin(@NonNull Constructor<T> constructor, @NonNull T thisObject, Object... args) throws InvocationTargetException, IllegalArgumentException, IllegalAccessException;
/**
* Invokes a special (non-virtual) method on a given object instance, similar to the functionality of
* {@code CallNonVirtual<type>Method} in JNI, which invokes an instance (nonstatic) method on a Java
* object. This method is useful when you need to call a specific method on an object, bypassing any
* overridden methods in subclasses and directly invoking the method defined in the specified class.
*
* <p>This method is useful when you need to call {@code super.xxx()} in a hooked constructor.</p>
*
* @param method The method to be called
* @param thisObject For non-static calls, the {@code this} pointer, otherwise {@code null}
* @param args The arguments used for the method call
* @return The result returned from the invoked method
* @see Method#invoke(Object, Object...)
*/
@Nullable
Object invokeSpecial(@NonNull Method method, @NonNull Object thisObject, Object... args) throws InvocationTargetException, IllegalArgumentException, IllegalAccessException;
/**
* Invokes a special (non-virtual) method on a given object instance, similar to the functionality of
* {@code CallNonVirtual<type>Method} in JNI, which invokes an instance (nonstatic) method on a Java
* object. This method is useful when you need to call a specific method on an object, bypassing any
* overridden methods in subclasses and directly invoking the method defined in the specified class.
*
* <p>This method is useful when you need to call {@code super.xxx()} in a hooked constructor.</p>
*
* @param constructor The constructor to create and initialize a new instance
* @param thisObject The instance to be constructed
* @param args The arguments used for the construction
* @see Constructor#newInstance(Object...)
*/
<T> void invokeSpecial(@NonNull Constructor<T> constructor, @NonNull T thisObject, Object... args) throws InvocationTargetException, IllegalArgumentException, IllegalAccessException;
/**
* Basically the same as {@link Constructor#newInstance(Object...)}, but calls the original constructor
* as it was before the interception by Xposed.
*
* @param <T> The type of the constructor
* @param constructor The constructor to create and initialize a new instance
* @param args The arguments used for the construction
* @return The instance created and initialized by the constructor
* @see Constructor#newInstance(Object...)
*/
@NonNull
<T> T newInstanceOrigin(@NonNull Constructor<T> constructor, Object... args) throws InvocationTargetException, IllegalArgumentException, IllegalAccessException, InstantiationException;
/**
* Creates a new instance of the given subclass, but initialize it with a parent constructor. This could
* leave the object in an invalid state, where the subclass constructor are not called and the fields
* of the subclass are not initialized.
*
* <p>This method is useful when you need to initialize some fields in the subclass by yourself.</p>
*
* @param <T> The type of the parent constructor
* @param <U> The type of the subclass
* @param constructor The parent constructor to initialize a new instance
* @param subClass The subclass to create a new instance
* @param args The arguments used for the construction
* @return The instance of subclass initialized by the constructor
* @see Constructor#newInstance(Object...)
*/
@NonNull
<T, U> U newInstanceSpecial(@NonNull Constructor<T> constructor, @NonNull Class<U> subClass, Object... args) throws InvocationTargetException, IllegalArgumentException, IllegalAccessException, InstantiationException;
/**
* Writes a message to the Xposed log.
*
* @param message The log message
*/
void log(@NonNull String message);
/**
* Writes a message with a stack trace to the Xposed log.
*
* @param message The log message
* @param throwable The Throwable object for the stack trace
*/
void log(@NonNull String message, @NonNull Throwable throwable);
/**
* Parse a dex file in memory.
*
* @param dexData The content of the dex file
* @param includeAnnotations Whether to include annotations
* @return The {@link DexParser} of the dex file
* @throws IOException if the dex file is invalid
*/
@Nullable
DexParser parseDex(@NonNull ByteBuffer dexData, boolean includeAnnotations) throws IOException;
/**
* Gets the application info of the module.
*/
@NonNull
ApplicationInfo getApplicationInfo();
/**
* Gets remote preferences stored in Xposed framework. Note that those are read-only in hooked apps.
*
* @param group Group name
* @return The preferences
* @throws UnsupportedOperationException If the framework is embedded
*/
@NonNull
SharedPreferences getRemotePreferences(@NonNull String group);
/**
* List all files in the module's shared data directory.
*
* @return The file list
* @throws UnsupportedOperationException If the framework is embedded
*/
@NonNull
String[] listRemoteFiles();
/**
* Open a file in the module's shared data directory. The file is opened in read-only mode.
*
* @param name File name, must not contain path separators and . or ..
* @return The file descriptor
* @throws FileNotFoundException If the file does not exist or the path is forbidden
* @throws UnsupportedOperationException If the framework is embedded
*/
@NonNull
ParcelFileDescriptor openRemoteFile(@NonNull String name) throws FileNotFoundException;
}

View File

@@ -0,0 +1,171 @@
package io.github.libxposed.api;
import android.content.SharedPreferences;
import android.content.pm.ApplicationInfo;
import android.os.ParcelFileDescriptor;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.nio.ByteBuffer;
import io.github.libxposed.api.utils.DexParser;
/**
* Wrap of {@link XposedInterface} used by the modules for the purpose of shielding framework implementation details.
*/
public class XposedInterfaceWrapper implements XposedInterface {
private final XposedInterface mBase;
XposedInterfaceWrapper(@NonNull XposedInterface base) {
mBase = base;
}
@NonNull
@Override
public final String getFrameworkName() {
return mBase.getFrameworkName();
}
@NonNull
@Override
public final String getFrameworkVersion() {
return mBase.getFrameworkVersion();
}
@Override
public final long getFrameworkVersionCode() {
return mBase.getFrameworkVersionCode();
}
@Override
public final int getFrameworkPrivilege() {
return mBase.getFrameworkPrivilege();
}
@NonNull
@Override
public final MethodUnhooker<Method> hook(@NonNull Method origin, @NonNull Class<? extends Hooker> hooker) {
return mBase.hook(origin, hooker);
}
@NonNull
@Override
public <T> MethodUnhooker<Constructor<T>> hookClassInitializer(@NonNull Class<T> origin, @NonNull Class<? extends Hooker> hooker) {
return mBase.hookClassInitializer(origin, hooker);
}
@NonNull
@Override
public <T> MethodUnhooker<Constructor<T>> hookClassInitializer(@NonNull Class<T> origin, int priority, @NonNull Class<? extends Hooker> hooker) {
return mBase.hookClassInitializer(origin, priority, hooker);
}
@NonNull
@Override
public final MethodUnhooker<Method> hook(@NonNull Method origin, int priority, @NonNull Class<? extends Hooker> hooker) {
return mBase.hook(origin, priority, hooker);
}
@NonNull
@Override
public final <T> MethodUnhooker<Constructor<T>> hook(@NonNull Constructor<T> origin, @NonNull Class<? extends Hooker> hooker) {
return mBase.hook(origin, hooker);
}
@NonNull
@Override
public final <T> MethodUnhooker<Constructor<T>> hook(@NonNull Constructor<T> origin, int priority, @NonNull Class<? extends Hooker> hooker) {
return mBase.hook(origin, priority, hooker);
}
@Override
public final boolean deoptimize(@NonNull Method method) {
return mBase.deoptimize(method);
}
@Override
public final <T> boolean deoptimize(@NonNull Constructor<T> constructor) {
return mBase.deoptimize(constructor);
}
@Nullable
@Override
public final Object invokeOrigin(@NonNull Method method, @Nullable Object thisObject, Object... args) throws InvocationTargetException, IllegalArgumentException, IllegalAccessException {
return mBase.invokeOrigin(method, thisObject, args);
}
@Override
public <T> void invokeOrigin(@NonNull Constructor<T> constructor, @NonNull T thisObject, Object... args) throws InvocationTargetException, IllegalArgumentException, IllegalAccessException {
mBase.invokeOrigin(constructor, thisObject, args);
}
@Nullable
@Override
public final Object invokeSpecial(@NonNull Method method, @NonNull Object thisObject, Object... args) throws InvocationTargetException, IllegalArgumentException, IllegalAccessException {
return mBase.invokeSpecial(method, thisObject, args);
}
@Override
public <T> void invokeSpecial(@NonNull Constructor<T> constructor, @NonNull T thisObject, Object... args) throws InvocationTargetException, IllegalArgumentException, IllegalAccessException {
mBase.invokeSpecial(constructor, thisObject, args);
}
@NonNull
@Override
public final <T> T newInstanceOrigin(@NonNull Constructor<T> constructor, Object... args) throws InvocationTargetException, IllegalArgumentException, IllegalAccessException, InstantiationException {
return mBase.newInstanceOrigin(constructor, args);
}
@NonNull
@Override
public final <T, U> U newInstanceSpecial(@NonNull Constructor<T> constructor, @NonNull Class<U> subClass, Object... args) throws InvocationTargetException, IllegalArgumentException, IllegalAccessException, InstantiationException {
return mBase.newInstanceSpecial(constructor, subClass, args);
}
@Override
public final void log(@NonNull String message) {
mBase.log(message);
}
@Override
public final void log(@NonNull String message, @NonNull Throwable throwable) {
mBase.log(message, throwable);
}
@Nullable
@Override
public final DexParser parseDex(@NonNull ByteBuffer dexData, boolean includeAnnotations) throws IOException {
return mBase.parseDex(dexData, includeAnnotations);
}
@NonNull
@Override
public SharedPreferences getRemotePreferences(@NonNull String name) {
return mBase.getRemotePreferences(name);
}
@NonNull
@Override
public ApplicationInfo getApplicationInfo() {
return mBase.getApplicationInfo();
}
@NonNull
@Override
public String[] listRemoteFiles() {
return mBase.listRemoteFiles();
}
@NonNull
@Override
public ParcelFileDescriptor openRemoteFile(@NonNull String name) throws FileNotFoundException {
return mBase.openRemoteFile(name);
}
}

View File

@@ -0,0 +1,21 @@
package io.github.libxposed.api;
import androidx.annotation.NonNull;
/**
* Super class which all Xposed module entry classes should extend.<br/>
* Entry classes will be instantiated exactly once for each process.
*/
@SuppressWarnings("unused")
public abstract class XposedModule extends XposedInterfaceWrapper implements XposedModuleInterface {
/**
* Instantiates a new Xposed module.<br/>
* When the module is loaded into the target process, the constructor will be called.
*
* @param base The implementation interface provided by the framework, should not be used by the module
* @param param Information about the process in which the module is loaded
*/
public XposedModule(@NonNull XposedInterface base, @NonNull ModuleLoadedParam param) {
super(base);
}
}

View File

@@ -0,0 +1,108 @@
package io.github.libxposed.api;
import android.content.pm.ApplicationInfo;
import android.os.Build;
import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
/**
* Interface for module initialization.
*/
@SuppressWarnings("unused")
public interface XposedModuleInterface {
/**
* Wraps information about the process in which the module is loaded.
*/
interface ModuleLoadedParam {
/**
* Gets information about whether the module is running in system server.
*
* @return {@code true} if the module is running in system server
*/
boolean isSystemServer();
/**
* Gets the process name.
*
* @return The process name
*/
@NonNull
String getProcessName();
}
/**
* Wraps information about system server.
*/
interface SystemServerLoadedParam {
/**
* Gets the class loader of system server.
*
* @return The class loader
*/
@NonNull
ClassLoader getClassLoader();
}
/**
* Wraps information about the package being loaded.
*/
interface PackageLoadedParam {
/**
* Gets the package name of the package being loaded.
*
* @return The package name.
*/
@NonNull
String getPackageName();
/**
* Gets the {@link ApplicationInfo} of the package being loaded.
*
* @return The ApplicationInfo.
*/
@NonNull
ApplicationInfo getApplicationInfo();
/**
* Gets default class loader.
*
* @return the default class loader
*/
@RequiresApi(Build.VERSION_CODES.Q)
@NonNull
ClassLoader getDefaultClassLoader();
/**
* Gets the class loader of the package being loaded.
*
* @return The class loader.
*/
@NonNull
ClassLoader getClassLoader();
/**
* Gets information about whether is this package the first and main package of the app process.
*
* @return {@code true} if this is the first package.
*/
boolean isFirstPackage();
}
/**
* Gets notified when a package is loaded into the app process.<br/>
* This callback could be invoked multiple times for the same process on each package.
*
* @param param Information about the package being loaded
*/
default void onPackageLoaded(@NonNull PackageLoadedParam param) {
}
/**
* Gets notified when the system server is loaded.
*
* @param param Information about system server
*/
default void onSystemServerLoaded(@NonNull SystemServerLoadedParam param) {
}
}

View File

@@ -0,0 +1,20 @@
package io.github.libxposed.api.errors;
/**
* Thrown to indicate that a hook failed due to framework internal error.
*/
@SuppressWarnings("unused")
public class HookFailedError extends XposedFrameworkError {
public HookFailedError(String message) {
super(message);
}
public HookFailedError(String message, Throwable cause) {
super(message, cause);
}
public HookFailedError(Throwable cause) {
super(cause);
}
}

View File

@@ -0,0 +1,19 @@
package io.github.libxposed.api.errors;
/**
* Thrown to indicate that the Xposed framework function is broken.
*/
public class XposedFrameworkError extends Error {
public XposedFrameworkError(String message) {
super(message);
}
public XposedFrameworkError(String message, Throwable cause) {
super(message, cause);
}
public XposedFrameworkError(Throwable cause) {
super(cause);
}
}

View File

@@ -0,0 +1,376 @@
package io.github.libxposed.api.utils;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import java.io.Closeable;
/**
* Xposed interface for parsing dex files.
*/
@SuppressWarnings("unused")
public interface DexParser extends Closeable {
/**
* The constant NO_INDEX.
*/
int NO_INDEX = 0xffffffff;
/**
* The interface Array.
*/
interface Array {
/**
* Get values value [ ].
*
* @return the value [ ]
*/
@NonNull
Value[] getValues();
}
/**
* The interface Annotation.
*/
interface Annotation {
/**
* Gets visibility.
*
* @return the visibility
*/
int getVisibility();
/**
* Gets type.
*
* @return the type
*/
@NonNull
TypeId getType();
/**
* Get elements element [ ].
*
* @return the element [ ]
*/
@NonNull
Element[] getElements();
}
/**
* The interface Value.
*/
interface Value {
/**
* Get value byte [ ].
*
* @return the byte [ ]
*/
@Nullable
byte[] getValue();
/**
* Gets value type.
*
* @return the value type
*/
int getValueType();
}
/**
* The interface Element.
*/
interface Element extends Value {
/**
* Gets name.
*
* @return the name
*/
@NonNull
StringId getName();
}
/**
* The interface Id.
*/
interface Id<Self> extends Comparable<Self> {
/**
* Gets id.
*
* @return the id
*/
int getId();
}
/**
* The interface Type id.
*/
interface TypeId extends Id<TypeId> {
/**
* Gets descriptor.
*
* @return the descriptor
*/
@NonNull
StringId getDescriptor();
}
/**
* The interface String id.
*/
interface StringId extends Id<StringId> {
/**
* Gets string.
*
* @return the string
*/
@NonNull
String getString();
}
/**
* The interface Field id.
*/
interface FieldId extends Id<FieldId> {
/**
* Gets type.
*
* @return the type
*/
@NonNull
TypeId getType();
/**
* Gets declaring class.
*
* @return the declaring class
*/
@NonNull
TypeId getDeclaringClass();
/**
* Gets name.
*
* @return the name
*/
@NonNull
StringId getName();
}
/**
* The interface Method id.
*/
interface MethodId extends Id<MethodId> {
/**
* Gets declaring class.
*
* @return the declaring class
*/
@NonNull
TypeId getDeclaringClass();
/**
* Gets prototype.
*
* @return the prototype
*/
@NonNull
ProtoId getPrototype();
/**
* Gets name.
*
* @return the name
*/
@NonNull
StringId getName();
}
/**
* The interface Proto id.
*/
interface ProtoId extends Id<ProtoId> {
/**
* Gets shorty.
*
* @return the shorty
*/
@NonNull
StringId getShorty();
/**
* Gets return type.
*
* @return the return type
*/
@NonNull
TypeId getReturnType();
/**
* Get parameters type id [ ].
*
* @return the type id [ ]
*/
@Nullable
TypeId[] getParameters();
}
/**
* Get string id string id [ ].
*
* @return the string id [ ]
*/
@NonNull
StringId[] getStringId();
/**
* Get type id type id [ ].
*
* @return the type id [ ]
*/
@NonNull
TypeId[] getTypeId();
/**
* Get field id field id [ ].
*
* @return the field id [ ]
*/
@NonNull
FieldId[] getFieldId();
/**
* Get method id method id [ ].
*
* @return the method id [ ]
*/
@NonNull
MethodId[] getMethodId();
/**
* Get proto id proto id [ ].
*
* @return the proto id [ ]
*/
@NonNull
ProtoId[] getProtoId();
/**
* Get annotations annotation [ ].
*
* @return the annotation [ ]
*/
@NonNull
Annotation[] getAnnotations();
/**
* Get arrays array [ ].
*
* @return the array [ ]
*/
@NonNull
Array[] getArrays();
/**
* The interface Early stop visitor.
*/
interface EarlyStopVisitor {
/**
* Stop boolean.
*
* @return the boolean
*/
boolean stop();
}
/**
* The interface Member visitor.
*/
interface MemberVisitor extends EarlyStopVisitor {
}
/**
* The interface Class visitor.
*/
interface ClassVisitor extends EarlyStopVisitor {
/**
* Visit member visitor.
*
* @param clazz the clazz
* @param accessFlags the access flags
* @param superClass the super class
* @param interfaces the interfaces
* @param sourceFile the source file
* @param staticFields the static fields
* @param staticFieldsAccessFlags the static fields access flags
* @param instanceFields the instance fields
* @param instanceFieldsAccessFlags the instance fields access flags
* @param directMethods the direct methods
* @param directMethodsAccessFlags the direct methods access flags
* @param virtualMethods the virtual methods
* @param virtualMethodsAccessFlags the virtual methods access flags
* @param annotations the annotations
* @return the member visitor
*/
@Nullable
MemberVisitor visit(int clazz, int accessFlags, int superClass, @NonNull int[] interfaces, int sourceFile, @NonNull int[] staticFields, @NonNull int[] staticFieldsAccessFlags, @NonNull int[] instanceFields, @NonNull int[] instanceFieldsAccessFlags, @NonNull int[] directMethods, @NonNull int[] directMethodsAccessFlags, @NonNull int[] virtualMethods, @NonNull int[] virtualMethodsAccessFlags, @NonNull int[] annotations);
}
/**
* The interface Field visitor.
*/
interface FieldVisitor extends MemberVisitor {
/**
* Visit.
*
* @param field the field
* @param accessFlags the access flags
* @param annotations the annotations
*/
void visit(int field, int accessFlags, @NonNull int[] annotations);
}
/**
* The interface Method visitor.
*/
interface MethodVisitor extends MemberVisitor {
/**
* Visit method body visitor.
*
* @param method the method
* @param accessFlags the access flags
* @param hasBody the has body
* @param annotations the annotations
* @param parameterAnnotations the parameter annotations
* @return the method body visitor
*/
@Nullable
MethodBodyVisitor visit(int method, int accessFlags, boolean hasBody, @NonNull int[] annotations, @NonNull int[] parameterAnnotations);
}
/**
* The interface Method body visitor.
*/
interface MethodBodyVisitor {
/**
* Visit.
*
* @param method the method
* @param accessFlags the access flags
* @param referredStrings the referred strings
* @param invokedMethods the invoked methods
* @param accessedFields the accessed fields
* @param assignedFields the assigned fields
* @param opcodes the opcodes
*/
void visit(int method, int accessFlags, @NonNull int[] referredStrings, @NonNull int[] invokedMethods, @NonNull int[] accessedFields, @NonNull int[] assignedFields, @NonNull byte[] opcodes);
}
/**
* Visit defined classes.
*
* @param visitor the visitor
* @throws IllegalStateException the illegal state exception
*/
void visitDefinedClasses(@NonNull ClassVisitor visitor) throws IllegalStateException;
}