安卓系统启动

什么zygote?

init是内核启动的第一个用户级进程,zygote是由init进程通过解析init.zygote.rc文件而创建的,zygote所对应的具体可执行程序是app_process,所对应的源文件是App_main.cpp,进程名称为zygote。

init.zygote.rc:

  1. service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
  2. class main
  3. socket zygote stream 660 root system
  4. onrestart write /sys/android_power/request_state wake
  5. onrestart write /sys/power/state on
  6. onrestart restart media
  7. onrestart restart netd
  8. writepid /dev/cpuset/foreground/tasks

安卓应用运行?

在ART模式下,zygote被init进程创建出来,用来孵化和启动其他App。zygote进程具有App所需要的所有核心库。

新的App进程在生成后,就会加载本App的程序代码(apk中的dex文件)

Xposed介绍

Xposed是安卓系统上能够修改系统或三方应用信息的框架。

Xposed构成

名称 介绍
Xposed Xposed框架Native部分
XposedBridge Xposed向开发者提供的API与相应工具类库
XposedInstaller Xposed框架Android端本地管理,环境框架,以及第三方module资源下载的工具

Xposed初始化大体工作流程

(1)xposed的主要接口在XposedBrigde.jar中,核心功能在替换的虚拟机中实现。

(2)app_process是Android App的启动程序(具体形式是zygote fork() 调用app_process作为Android app的载体)。

源码分析

初始化

app_process有两个对应源文件,Android.mk会在编译时根据sdk版本选择对应源文件作为入口(app_main.cpp或app_main2.cpp)

  1. ...
  2. ifeq (1,$(strip $(shell expr $(PLATFORM_SDK_VERSION) \>= 21)))
  3. LOCAL_SRC_FILES := app_main2.cpp
  4. LOCAL_MULTILIB := both
  5. LOCAL_MODULE_STEM_32 := app_process32_xposed
  6. LOCAL_MODULE_STEM_64 := app_process64_xposed
  7. else
  8. LOCAL_SRC_FILES := app_main.cpp
  9. LOCAL_MODULE_STEM := app_process_xposed
  10. endif
  11. ...
  12. ifeq (1,$(strip $(shell expr $(PLATFORM_SDK_VERSION) \>= 21)))
  13. include frameworks/base/cmds/xposed/ART.mk
  14. else
  15. include frameworks/base/cmds/xposed/Dalvik.mk
  16. endif

app_main#main

在系统开机时,会通过app_process去创建zygote虚拟机,就会调用到app_main2.cpp中的main函数。

main函数中主要做两件事:(1)初始化xposed;(2)创建虚拟机

  1. int main(int argc, char* const argv[])
  2. {
  3. if (xposed::handleOptions(argc, argv))
  4. return 0;
  5. //代码省略...
  6. runtime.mParentDir = parentDir;
  7. // 初始化xposed,主要是将jar包添加至Classpath中
  8. isXposedLoaded = xposed::initialize(zygote, startSystemServer, className, argc, argv);
  9. if (zygote) {
  10. // 如果xposed初始化成功,将zygoteInit 替换为 de.robv.android.xposed.XposedBridge,然后创建虚拟机
  11. runtime.start(isXposedLoaded ? XPOSED_CLASS_DOTS_ZYGOTE : "com.android.internal.os.ZygoteInit",
  12. startSystemServer ? "start-system-server" : "");
  13. }
  14. ...
  15. }

app_main#initialize

初始化xposed

(1)初始化xposed内相关变量

(2)调用addJarToClasspath将XposedBridge.jar添加至系统目录。

  1. bool initialize(bool zygote, bool startSystemServer, const char* className, int argc, char* const argv[]) {
  2. ...
  3. // 初始化xposed的相关变量
  4. xposed->zygote = zygote;
  5. xposed->startSystemServer = startSystemServer;
  6. xposed->startClassName = className;
  7. xposed->xposedVersionInt = xposedVersionInt;
  8. ...
  9. // 打印 release、sdk、manufacturer、model、rom、fingerprint、platform相关数据
  10. printRomInfo();
  11. // 主要在于将jar包加入Classpath
  12. return addJarToClasspath();
  13. }

frameworks.base.core.jni.AndroidRuntime#start

创建对应虚拟机

start做了4件事:

(1)创建虚拟机

(2)初始化虚拟机

(3)传入调用类de.robv.android.xposed.XposedBridge

(4)初始化XposedBridge

  1. /*
  2. * Start the Android runtime. This involves starting the virtual machine
  3. * and calling the "static void main(String[] args)" method in the class
  4. * named by "className".
  5. *
  6. * Passes the main function two arguments, the class name and the specified
  7. * options string.
  8. */
  9. void AndroidRuntime::start(const char* className, const Vector<String8>& options)
  10. {
  11. /* start the virtual machine */
  12. JniInvocation jni_invocation;
  13. jni_invocation.Init(NULL);
  14. JNIEnv* env;
  15. //创建虚拟机
  16. if (startVm(&mJavaVM, &env) != 0) {
  17. return;
  18. }
  19. // 初始化虚拟机,xposed对虚拟机进行修改
  20. onVmCreated(env);
  21. // 虚拟机初始化完成后,会调用传入的de.robv.android.xposed.XposedBridge类,初始化java层XposedBridge.jar
  22. char* slashClassName = toSlashClassName(className);
  23. jclass startClass = env->FindClass(slashClassName);
  24. if (startClass == NULL) {
  25. ...
  26. } else {
  27. jmethodID startMeth = env->GetStaticMethodID(startClass, "main",
  28. ...
  29. }
  30. }

Xposed.cpp#onVmCreated

xposed重写了onVmCreated。

onVmCreated做了什么:

1、xposedInitLib->onVmCreatedCommon->initXposedBridge,初始化XposedBridge

(1)将register_natives_XposedBridge中的函数注册为Native方法

2、xposedInitLib->onVmCreatedCommon->onVmCreated,为xposed_callback_class与xposed_callback_method赋值;

(1)xposed_callback_class和xposed_callback_method变量赋值

3、 de.robv.android.xposed.XposedBridge#main,初始化java层XposedBridge.jar

(1)hook 住系统资源相关的方法;

(2)hook 住zygote 的相关方法;

(3)加载系统中已经安装的xposed 模块。

  1. void onVmCreated(JNIEnv* env) {
  2. // Determine the currently active runtime
  3. ...
  4. // Load the suitable libxposed_*.so for it 通过dlopen加载libxposed_art.so
  5. void* xposedLibHandle = dlopen(xposedLibPath, RTLD_NOW);
  6. ...
  7. // Initialize the library 初始化xposed相关库
  8. bool (*xposedInitLib)(XposedShared* shared) = NULL;
  9. // 根据动态链接库操作句柄与符号,返回符号对应的地址
  10. *(void **) (&xposedInitLib) = dlsym(xposedLibHandle, "xposedInitLib");
  11. if (!xposedInitLib) {
  12. ALOGE("Could not find function xposedInitLib");
  13. return;
  14. }
  15. ...
  16. // xposedInitLib -> onVmCreatedCommon -> initXposedBridge -> 注册Xposed相关Native方法
  17. if (xposedInitLib(xposed)) {
  18. xposed->onVmCreated(env);
  19. }
  20. }

libxposed_art.cpp#xposedInitLib

  1. /** Called by Xposed's app_process replacement. */
  2. bool xposedInitLib(XposedShared* shared) {
  3. xposed = shared;
  4. xposed->onVmCreated = &onVmCreatedCommon;
  5. return true;
  6. }

libxposed_common.cpp#onVmCreatedCommon

  1. void onVmCreatedCommon(JNIEnv* env) {
  2. if (!initXposedBridge(env) || !initZygoteService(env)) {
  3. return;
  4. }
  5. if (!onVmCreated(env)) {
  6. return;
  7. }
  8. xposedLoadedSuccessfully = true;
  9. return;
  10. }

libxposed_common.cpp#initXposedBridge

  1. bool initXposedBridge(JNIEnv* env) {
  2. classXposedBridge = env->FindClass(CLASS_XPOSED_BRIDGE);
  3. ...
  4. classXposedBridge = reinterpret_cast<jclass>(env->NewGlobalRef(classXposedBridge));
  5. ALOGI("Found Xposed class '%s', now initializing", CLASS_XPOSED_BRIDGE);
  6. // 将register_natives_XposedBridge中的函数注册为Native方法
  7. if (register_natives_XposedBridge(env, classXposedBridge) != JNI_OK) {
  8. ALOGE("Could not register natives for '%s'", CLASS_XPOSED_BRIDGE);
  9. logExceptionStackTrace();
  10. env->ExceptionClear();
  11. return false;
  12. }
  13. // 获取XposedBridge.jar中的handleHookedMethod方法,并将该方法赋值给methodXposedBridgeHandleHookedMethod,后续会赋值至全局变量中
  14. methodXposedBridgeHandleHookedMethod = env->GetStaticMethodID(classXposedBridge, "handleHookedMethod",
  15. "(Ljava/lang/reflect/Member;ILjava/lang/Object;Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;");
  16. ...
  17. return true;
  18. }

libxposed_art.cpp#onVmCreated

  1. /** Called very early during VM startup. */
  2. bool onVmCreated(JNIEnv*) {
  3. // TODO: Handle CLASS_MIUI_RESOURCES?
  4. ArtMethod::xposed_callback_class = classXposedBridge;
  5. ArtMethod::xposed_callback_method = methodXposedBridgeHandleHookedMethod;
  6. return true;
  7. }

de.robv.android.xposed.XposedBridge#main

虚拟机初始化完成后,会调用传入的de.robv.android.xposed.XposedBridge类,初始化java层XposedBridge.jar,调用main函数

(1)hook 系统资源相关的方法;

(2)hook zygote 的相关方法;

(3)加载系统中已经安装的xposed 模块。

  1. protected static void main(String[] args) {
  2. // Initialize the Xposed framework and modules
  3. try {
  4. if (!hadInitErrors()) {
  5. initXResources();
  6. SELinuxHelper.initOnce();
  7. SELinuxHelper.initForProcess(null);
  8. runtime = getRuntime();
  9. XPOSED_BRIDGE_VERSION = getXposedVersion();
  10. if (isZygote) {
  11. XposedInit.hookResources();
  12. XposedInit.initForZygote();
  13. }
  14. XposedInit.loadModules();
  15. } else {
  16. Log.e(TAG, "Not initializing Xposed because of previous errors");
  17. }
  18. }
  19. // Call the original startup code
  20. if (isZygote) {
  21. ZygoteInit.main(args);
  22. } else {
  23. RuntimeInit.main(args);
  24. }
  25. }

初始化结束。

例子

  1. static final String TAG = "XposedTest001";
  2. //final XC_MethodReplacement replacementTrue = XC_MethodReplacement.returnConstant(true);
  3. public CheckSNHook(ClassLoader cl) {
  4. super();
  5. XposedBridge.log("hooking checkSN.");
  6. try {
  7. Class clz = (Class<?>) XposedHelpers.findClass("com.droider.crackme0201.MainActivity", cl);
  8. //XposedBridge.hookAllMethods(clz, "checkSN", replacementTrue);
  9. Log.d(TAG, "hooking clz");
  10. XposedHelpers.findAndHookMethod(clz,
  11. "checkSN",
  12. String.class, String.class,
  13. new XC_MethodHook() {
  14. @Override
  15. protected void afterHookedMethod(MethodHookParam param)
  16. throws Throwable {
  17. XposedBridge.log("1CheckSN afterHookedMethod called.");
  18. String s1 = (String) param.args[0];
  19. String s2 = (String) param.args[1];
  20. Log.d(TAG, "s1:" + s1);
  21. Log.d(TAG, "s2:" + s2);
  22. param.setResult(true);
  23. super.afterHookedMethod(param);
  24. }
  25. });
  26. } catch (Exception e) {
  27. e.printStackTrace();
  28. }
  29. XposedBridge.log("1hook checkSN done.");
  30. }

Hook原理分析

XposedBridge#findAndHookMethod

1、根据函数名获取对应Method对象

2、调用XposedBridge.hookMethod函数

  1. public static XC_MethodHook.Unhook findAndHookMethod(Class<?> clazz, String methodName, Object... parameterTypesAndCallback) {
  2. if (parameterTypesAndCallback.length == 0 || !(parameterTypesAndCallback[parameterTypesAndCallback.length-1] instanceof XC_MethodHook))
  3. throw new IllegalArgumentException("no callback defined");
  4. // 封装回调函数
  5. XC_MethodHook callback = (XC_MethodHook) parameterTypesAndCallback[parameterTypesAndCallback.length-1];
  6. // 主要函数Method method = clazz.getDeclaredMethod(methodName, parameterTypes);
  7. Method m = findMethodExact(clazz, methodName, getParameterClasses(clazz.getClassLoader(), parameterTypesAndCallback));
  8. // 核心函数
  9. return XposedBridge.hookMethod(m, callback);
  10. }

XposedBridge#hookMethod

1、将回调函数、参数类型、返回类型记录到AdditionalHookInfo中

2、拦截指定函数调用,并使用其他函数替代(native函数)

  1. public static XC_MethodHook.Unhook hookMethod(Member hookMethod, XC_MethodHook callback) {
  2. ...
  3. // 将回调函数、参数类型、返回类型记录到AdditionalHookInfo中
  4. AdditionalHookInfo additionalInfo = new AdditionalHookInfo(callbacks, parameterTypes, returnType);
  5. // 拦截指定函数调用,并使用其他函数替代
  6. hookMethodNative(hookMethod, declaringClass, slot, additionalInfo);
  7. }
  8. return callback.new Unhook(hookMethod);
  9. }
  10. private native synchronized static void hookMethodNative(Member method, Class<?> declaringClass, int slot, Object additionalInfo);

libxposed.cpp#hookMethodNative

1、查找我们需要hook的java Method对应的ArtMethod (每一个java层函数在ART下都有一个对应的ArtMethod)

  1. void XposedBridge_hookMethodNative(JNIEnv* env, jclass, jobject javaReflectedMethod,
  2. jobject, jint, jobject javaAdditionalInfo) {
  3. ...
  4. // 获取Java层Method对应native层的ArtMethod指针,将java函数描述为ArtMethod,查找我们需要hook的java Method对应的ArtMethod
  5. ArtMethod* artMethod = ArtMethod::FromReflectedMethod(soa, javaReflectedMethod);
  6. // Hook the method
  7. artMethod->EnableXposedHook(soa, javaAdditionalInfo);
  8. }

EnableXposedHook

1、创建原函数备份

2、创建 XposedHookInfo 保存原函数、before函数、after函数

3、设置机器指令入口地址,此时跳入到GetQuickProxyInvokeHandler()地址

  1. void ArtMethod::EnableXposedHook(ScopedObjectAccess& soa, jobject additional_info) {
  2. ...
  3. // 创建原函数备份
  4. auto* cl = Runtime::Current()->GetClassLinker();
  5. auto* linear_alloc = cl->GetAllocatorForClassLoader(GetClassLoader());
  6. ArtMethod* backup_method = cl->CreateRuntimeMethod(linear_alloc);
  7. backup_method->CopyFrom(this, cl->GetImagePointerSize());
  8. // 设置标识符kAccXposedOriginalMethod
  9. backup_method->SetAccessFlags(backup_method->GetAccessFlags() | kAccXposedOriginalMethod);
  10. // Create a Method/Constructor object for the backup ArtMethod object
  11. mirror::AbstractMethod* reflected_method;
  12. if (IsConstructor()) {
  13. reflected_method = mirror::Constructor::CreateFromArtMethod(soa.Self(), backup_method);
  14. } else {
  15. reflected_method = mirror::Method::CreateFromArtMethod(soa.Self(), backup_method);
  16. }
  17. reflected_method->SetAccessible<false>(true);
  18. // 创建 XposedHookInfo 保存原函数、before函数、after函数(reflected_method:被hook的函数,XposedHookInfo包含回调函数)
  19. XposedHookInfo* hook_info = reinterpret_cast<XposedHookInfo*>(linear_alloc->Alloc(soa.Self(), sizeof(XposedHookInfo)));
  20. hook_info->reflected_method = soa.Vm()->AddGlobalRef(soa.Self(), reflected_method);
  21. hook_info->additional_info = soa.Env()->NewGlobalRef(additional_info);
  22. hook_info->original_method = backup_method;
  23. ...
  24. //将entry_point_from_jni_指针指向hook信息(目的是存储),hook信息包括原函数、before函数、after函数
  25. SetEntryPointFromJniPtrSize(reinterpret_cast<uint8_t*>(hook_info), sizeof(void*));
  26. // 设置机器指令入口地址,此时跳入到GetQuickProxyInvokeHandler()地址
  27. SetEntryPointFromQuickCompiledCode(GetQuickProxyInvokeHandler());
  28. SetCodeItemOffset(0);
  29. // Adjust access flags.
  30. // 进行标志位清除,此时这个ArtMethod对象对应是Hook后的方法,这个方法的实现不是native的
  31. const uint32_t kRemoveFlags = kAccNative | kAccSynchronized | kAccAbstract | kAccDefault | kAccDefaultConflict;
  32. SetAccessFlags((GetAccessFlags() & ~kRemoveFlags) | kAccXposedHookedMethod);
  33. MutexLock mu(soa.Self(), *Locks::thread_list_lock_);
  34. Runtime::Current()->GetThreadList()->ForEach(StackReplaceMethodAndInstallInstrumentation, this);
  35. }

artQuickProxyInvokeHandler

  1. extern "C" uint64_t artQuickProxyInvokeHandler(
  2. ArtMethod* proxy_method, mirror::Object* receiver, Thread* self, ArtMethod** sp)
  3. const bool is_xposed = proxy_method->IsXposedHookedMethod();//判断 GetAccessFlags() 的kAccXposedHookedMethod 字段
  4. ......
  5. if (is_xposed) {
  6. jmethodID proxy_methodid = soa.EncodeMethod(proxy_method);
  7. self->EndAssertNoThreadSuspension(old_cause);
  8. JValue result = InvokeXposedHandleHookedMethod(soa, shorty, rcvr_jobj, proxy_methodid, args);
  9. local_ref_visitor.FixupReferences();
  10. return result.GetJ();
  11. }
  12. ......
  13. }

InvokeXposedHandleHookedMethod

  1. JValue InvokeXposedHandleHookedMethod(ScopedObjectAccessAlreadyRunnable& soa, const char* shorty, jobject rcvr_jobj, jmethodID method, std::vector<jvalue>& args) {
  2. //获取ArtMethod 的 hookinfo 信息,该信息是EntryPointFromJniPtrSize所指向的信息
  3. const XposedHookInfo* hookInfo = soa.DecodeMethod(method)->GetXposedHookInfo();
  4. //将hookinfo 转为一个数组,以便和java 层进行通信调用
  5. jvalue invocation_args[5];
  6. invocation_args[0].l = hookInfo->reflectedMethod;
  7. invocation_args[1].i = 1;
  8. invocation_args[2].l = hookInfo->additionalInfo;
  9. invocation_args[3].l = rcvr_jobj;
  10. invocation_args[4].l = args_jobj;
  11. //通过CallStaticObjectMethodA 调用 xposed_callback_class 类里面 xposed_callback_method 的方法
  12. //xposed_callback_class: XposedBridge.java
  13. //xposed_callback_method: handleHookedMethod 方法
  14. //ArtMethod 的这两个值,在系统开机时 在 onVmCreated 进行赋值的
  15. jobject result = soa.Env()->CallStaticObjectMethodA(ArtMethod::xposed_callback_class,
  16. ArtMethod::xposed_callback_method,
  17. invocation_args);
  18. }

InvokeXposedHandleHookedMethod

(1)获取ArtMethod 的 hookinfo 信息,该信息是EntryPointFromJniPtrSize所指向的信息

(2)通过CallStaticObjectMethodA 调用 xposed_callback_class 类里面 xposed_callback_method 的方法

(3)此处xposed_callback_class,xposed_callback_method 是libxposed_art****.cpp#onVmCreated重写时做的事

  1. const XposedHookInfo* GetXposedHookInfo() {
  2. DCHECK(IsXposedHookedMethod());
  3. // 前面存储EntryPointFromJniPtrSize指向的信息
  4. return reinterpret_cast<const XposedHookInfo*>(GetEntryPointFromJniPtrSize(sizeof(void*)));
  5. }

GetXposedHookInfo:获取EntryPointFromJniPtrSize存储的信息

Xposed.java#handleHookedMethod

  1. private static Object handleHookedMethod(Member method, int originalMethodId, Object additionalInfoObj,
  2. Object thisObject, Object[] args) throws Throwable {
  3. AdditionalHookInfo additionalInfo = (AdditionalHookInfo) additionalInfoObj;
  4. ...
  5. // call "before method" callbacks
  6. int beforeIdx = 0;
  7. do {
  8. try {
  9. ((XC_MethodHook) callbacksSnapshot[beforeIdx]).beforeHookedMethod(param);
  10. } catch (Throwable t) {
  11. XposedBridge.log(t);
  12. // reset result (ignoring what the unexpectedly exiting callback did)
  13. param.setResult(null);
  14. param.returnEarly = false;
  15. continue;
  16. }
  17. if (param.returnEarly) {
  18. // skip remaining "before" callbacks and corresponding "after" callbacks
  19. beforeIdx++;
  20. break;
  21. }
  22. } while (++beforeIdx < callbacksLength);
  23. // call original method if not requested otherwise
  24. if (!param.returnEarly) {
  25. try {
  26. param.setResult(invokeOriginalMethodNative(method, originalMethodId,
  27. additionalInfo.parameterTypes, additionalInfo.returnType, param.thisObject, param.args));
  28. } catch (InvocationTargetException e) {
  29. param.setThrowable(e.getCause());
  30. }
  31. }
  32. // call "after method" callbacks
  33. int afterIdx = beforeIdx - 1;
  34. do {
  35. Object lastResult = param.getResult();
  36. Throwable lastThrowable = param.getThrowable();
  37. try {
  38. ((XC_MethodHook) callbacksSnapshot[afterIdx]).afterHookedMethod(param);
  39. } catch (Throwable t) {
  40. XposedBridge.log(t);
  41. // reset to last result (ignoring what the unexpectedly exiting callback did)
  42. if (lastThrowable == null)
  43. param.setResult(lastResult);
  44. else
  45. param.setThrowable(lastThrowable);
  46. }
  47. } while (--afterIdx >= 0);
  48. // return
  49. if (param.hasThrowable())
  50. throw param.getThrowable();
  51. else
  52. return param.getResult();
  53. }

XposedBridge.java 类的handleHookedMethod 方法,真正去处理 before、Original、after 这三个方法的调用关系。

ART函数调用原理

每一个Java函数在ART(虚拟机)内部都由一个ArtMethod对象表示,ArtMethod对象中包含了函数名、参数类型、方法体代码入口地址等。

  1. class ArtMethod {
  2. ...
  3. protect:
  4. HeapReference<Class> declaring_class_;
  5. HeapReference<ObjectArray<ArtMethod>> dex_cache_resolved_methods_;
  6. HeapReference<ObjectArray<Class>> dex_cache_resolved_types_;
  7. uint32_t access_flags_;
  8. uint32_t dex_code_item_offset_;
  9. uint32_t dex_method_index_;
  10. uint32_t method_index_;
  11. struct PACKED(4) PtrSizedFields {
  12. void* entry_point_from_interpreter_;
  13. // 用于存储jni函数信息,非jni函数的无用,所以经常被hook框架将原方法保存在entry_point_from_jni_
  14. void* entry_point_from_jni_;
  15. // ART HOOK常见的方法是替换入口点,执行hook的函数。(此处指向的是汇编代码,运行的是已经预处理过的机器码)
  16. void* entry_point_from_quick_compiled_code_;
  17. #if defined(ART_USE_PORTABLE_COMPILER)
  18. void* entry_point_from_portable_compiled_code_;
  19. #endif
  20. } ptr_sized_fields_;
  21. static GcRoot<Class> java_lang_reflect_ArtMethod_;

替换entrypoint。将原函数对应的ArtMethod对象中entrypoint指向的机器码替换为目标函数的机器码,即可达到hook的目的。

总结

(1)准备包名、函数、参数类型、回调函数调用Hook接口

(2)Xposed在找到art虚拟机中找到方法对应的ArtMethod对象

(3)对ArtMethod对象进行备份

(4)修改备份对象的机器指令入口

(5)回调handleHookedMethod函数

参考

Xposed 源码剖析1(初始话相关):https://blog.csdn.net/xiaolli/article/details/107506138

Xposed 源码剖析2:https://blog.csdn.net/a314131070/article/details/81092526

Xposed 源码剖析3:https://blog.csdn.net/a314131070/article/details/81092548

Xposed 源码剖析4:https://blog.csdn.net/xiaolli/article/details/107517039

Xposed 源码剖析5:https://egguncle.github.io/2018/02/04/xposed-art-hook-%E6%B5%85%E6%9E%90/

Xposed dalvik 源码剖析6:https://bbs.pediy.com/thread-247030.htm

ART入口点替换分析:https://www.jianshu.com/p/820eceabf219

ArtMethod结构:https://zhuanlan.zhihu.com/p/92267192

ArtMethod结构:https://bbs.pediy.com/thread-248898.htm

Dalvik与ART:https://www.jianshu.com/p/59d98244fb52

定制xposed:https://blog.csdn.net/qq_35834055/article/details/103256122

Xposed原理分析的更多相关文章

  1. xposed 原理分析

    1.添加hook方法 首先是init进程打开 app_process,然后进入XposedInit.java main() - > initForZygote() 加入对ActivityThre ...

  2. 阿里系产品Xposed Hook检测机制原理分析

    阿里系产品Xposed Hook检测机制原理分析 导语: 在逆向分析android App过程中,我们时常用的用的Java层hook框架就是Xposed Hook框架了.一些应用程序厂商为了保护自家a ...

  3. Handler系列之原理分析

    上一节我们讲解了Handler的基本使用方法,也是平时大家用到的最多的使用方式.那么本节让我们来学习一下Handler的工作原理吧!!! 我们知道Android中我们只能在ui线程(主线程)更新ui信 ...

  4. Java NIO使用及原理分析(1-4)(转)

    转载的原文章也找不到!从以下博客中找到http://blog.csdn.net/wuxianglong/article/details/6604817 转载自:李会军•宁静致远 最近由于工作关系要做一 ...

  5. 原子类java.util.concurrent.atomic.*原理分析

    原子类java.util.concurrent.atomic.*原理分析 在并发编程下,原子操作类的应用可以说是无处不在的.为解决线程安全的读写提供了很大的便利. 原子类保证原子的两个关键的点就是:可 ...

  6. Android中Input型输入设备驱动原理分析(一)

    转自:http://blog.csdn.net/eilianlau/article/details/6969361 话说Android中Event输入设备驱动原理分析还不如说Linux输入子系统呢,反 ...

  7. 转载:AbstractQueuedSynchronizer的介绍和原理分析

    简介 提供了一个基于FIFO队列,可以用于构建锁或者其他相关同步装置的基础框架.该同步器(以下简称同步器)利用了一个int来表示状态,期望它能够成为实现大部分同步需求的基础.使用的方法是继承,子类通过 ...

  8. Camel运行原理分析

    Camel运行原理分析 以一个简单的例子说明一下camel的运行原理,例子本身很简单,目的就是将一个目录下的文件搬运到另一个文件夹,处理器只是将文件(限于文本文件)的内容打印到控制台,首先代码如下: ...

  9. NOR Flash擦写和原理分析

    NOR Flash擦写和原理分析 1. NOR FLASH 的简单介绍 NOR FLASH 是很常见的一种存储芯片,数据掉电不会丢失.NOR FLASH支持Execute On Chip,即程序可以直 ...

随机推荐

  1. Howdoo欢迎Mitel成为内容发布支持者

    原文链接:https://medium.com/howdoo/howdoo-welcomes-mitel-as-a-launch-supporter-4c40027d4dd1 “Mitel很高兴能够成 ...

  2. 二、kafka 中央控制器、主题、分区、副本

    集群和中央控制器 一个独立的Kafka服务器被称为broker.broker用来接收来自生产者的消息,为消息设置偏移量,并把消息保存到磁盘.换句话说,多个kafka实例组成kafka集群,每个实例(s ...

  3. 准备开始了解orchardcore,有兴趣的一起啊

    orchardcore网上的资料真是少,开始看源码,目前遇到的最大问题是不知道ModuleName属性如何自动注入到OrchardCore.Cms.Web的程序集Assembly上面,等这个搞通了估计 ...

  4. Linux多任务编程之三:exec函数族及其基础实验(转)

    来源:CSDN  作者:王文松  转自:Linux公社 exec函数族 函数族说明 fork() 函数用于创建一个新的子进程,该子进程几乎复制了父进程的全部内容,但是,这个新创建的子进程如何执行呢?e ...

  5. Jenkins - 解决集成 jmeter+ant 发送邮件时报错:java.lang.ClassNotFoundException: javax.mail.internet.MimeMessage

    jenkins + jmeter +ant 发送邮件失败 问题原因 其实就是缺失 jar 包,导致某些类找不到了 解决方案 点击该网站,下载commons-email.jar包 点击该网站,下载act ...

  6. Elasticsearch 内存配置应用案例

    Elasticsearch 内存配置 有三个可选项: 你主要做全文检索吗?考虑给 Elasticsearch 4 - 32 GB 的内存, 让 Lucene 通过操作系统文件缓存来利用余下的内存.那些 ...

  7. 机器学习实战基础(三十五):随机森林 (二)之 RandomForestClassifier 之重要参数

    RandomForestClassifier class sklearn.ensemble.RandomForestClassifier (n_estimators=’10’, criterion=’g ...

  8. 用Eclipse进行单元测试JUnit4

    (1)在项目中引入Jar包 (2)编写需要测试的类 public class Calculator {     private static int result=0; // 静态变量,用于存储运行结 ...

  9. oracle 在物理机上添加磁盘操作

    物理机上添加磁盘操作 注意:1)物理机上添加磁盘操作,不涉及到start_udev的动作.2)磁盘分区的操作,需要谨慎进行,核准无误后再操作. (1)查看磁盘名称命名 # su - grid$ sql ...

  10. Android 性能优化---布局优化

    Android 性能优化---布局优化 Android 布局绘制原理 布局加载过程 setContentView() --> inflate() -- > getLayout()(I/O操 ...