android_Xposed框架/init.rc语音/jni/android启动





  Xposed框架:
  RootAccess:因为Xposed工作原理是在/system/bin目录下替换文件,在install的时候需要root权限,但是运行时不需要root权限.
  XposedMods:使用Xposed开发的一些Modules,其中AppSettings是一个可以进行权限动态管理的应用
  Xposed是rovo89针对Android平台的动态劫持项目,通过替换/system/bin/app_process程序控制zygote进程,使得app_process在启动过程中会加载XposedBridge.jar这个jar包,从而完成对Zygote进程及其创建的Dalvik虚拟机的劫持;
  与采取传统的Inhook方式(详见Dynamic Dalvik Instrumentation分析这篇本章)相比,Xposed在开机的时候完成对所有的HookFunction的劫持,在原Function执行的前后加上自定义代码;
  Xposed框架中起作用的是对方法的hook;在Repackage技术中,如果对APK做修改,则需要修改Smali代码中的指令;而另一种动态修改指令的技术需要在程序运行时基于匹配搜索来替换smali代码,但因为方法声明的多样性与复杂性,该法比较复杂;
  在Android系统启动时,zygote进程加载XposedBridge将所有需要替换的Method通过JNI方法hookMethodNative指向Native方法xposedCallHandler,xposedCallHandler在转入handleHookedMethod这个Java方法执行用户规定的HookFunc;
  1.XposedInstaller:InstallerFragment类private String install();  执行app_process的替换与XposedBridge.jar的写入操作;
  $cp -a /system/bin/app_process /system/bin/app_process.orig;#备份原有  #把自己的app_process_xposed写入;
  $sync;#将有关文件系统的存储器常驻信息送入物理介质内;在暂停系统之前,比如要重新启动机器,一定要去执行sync命令;
  XposedInstaller是Xposed的安装包,负责配置Xposed工作的环境并且提供对基于Xposed框架的Modules的管理;在安装XposedInstaller之后,app_process与XposedBridge.jar放置在了/data/data/de.robv.android.xposed.installer;
  2.Xposed:
  Xposed的C++部分,主要是用来替换/system/bin/app_process,并为XposedBridge提供JNI方法;
  3.XposedBridge:
  XposedBridge.jar文件本质上是由XposedBridge生成的APK文件更名而来;入口,XposedBridge.main();由app_main.cpp的main函数调用;
  XposedBridge.jar是Xposed提供的jar文件,负责在Native层与FrameWork层进行交互;/system/bin/app_process进程启动过程中会加载该jar包,其它的Modules的开发与运行都是基于该jar包的;
  XposedBridge有一个私有的Native(JNI)方法hookMethodNative,这个方法也在app_process中使用;这个函数提供一个方法对象利用Java的Reflection机制来对内置方法覆写;
  XposedBridge类initXbridgeZygote():Hook系统关键函数,主要是调用XposedHelpers类中的findAndHookMethod完成;

  Xposed原理:
  Zygote,在Android系统中,应用程序进程都是由Zygote进程孵化出来的,而Zygote进程是由Init进程启动的;
  Zygote进程在启动时会创建一个Dalvik虚拟机实例,每当它孵化一个新的应用程序进程时,都会将这个Dalvik虚拟机实例复制到新的应用程序进程里面去,从而使得每一个应用程序进程都有一个独立的Dalvik虚拟机实例;
  在Android系统启动时,zygote进程加载XposedBridge将所有需要替换的Method通过JNI方法hookMethodNative指向Native方法xposedCallHandler,xposedCallHandler在转入handleHookedMethod这个Java方法执行用户规定的HookFunc;
  在hookMethodNative的实现中,会调用XposedBridge中的handleHookedMethod这个方法来传递参数;
  handleHookedMethod这个方法类似于一个统一调度的Dispatch例程,其对应的底层的C++函数是xposedCallHandler;
  handleHookedMethod实现里面会根据一个全局结构hookedMethodCallbacks来选择相应的hook函数,并调用他们的before,after函数;
  XposedBridge的main()函数,由Zygote跳入XposedBridge执行的第一个函数;
  XposedBridge的java代码中没有so文件,它的native方法是在xposed的c代码中实现的;即在被替换的app_main中加载,通过env->RegisterNatives(*)方式;
  app_main.cpp中onVmCreated(*),调用了xposed.cpp的xposedOnVmCreated(*);  xposedOnVmCreated()调用了RegisterNatives(*);
  app_main.cpp的main函数,根据配置决定调用Xposed;    AppRuntime runtime;
  启动zygote: runtime.start(keepLoadingXposed ? "de.robv.android.xposed.XposedBridge":"com.android.internal.os.ZygoteInit", startSystemServer ? "start-system-server" : "");
  启动className: runtime.start(keepLoadingXposed ? "de.robv.android.xposed.XposedBridge":"com.android.internal.os.RuntimeInit", application ? "application" : "tool");
  Xposed在onVmCreated(JNIEnv* env)中完成了自身JNI方法的注册;



  xposed已经成型的Demo:
  显示cpu温度;显示cpu使用率;显示网络信号强度;显示内存使用率;statusBar显示wifi名称;双击statusBar进入休眠;Toast中现显示应用Icon;关机弹出多选选择对话框;
  去掉充满电警告;去掉电量低自动关机;修改app名字;app数据保护;向statusBar中添加文字;设置应用的设置参数注入;锁屏壁纸;打电话全屏显示图像;来电拦截;隐藏app;FM选择;
  添加aosp的菜单;下拉日期显示阴历;修改framework-res.apk;禁止Toast提示;修改音量上下的响应;短信SmileyRplacer;去掉截屏延时;隐藏root授权;监控启动程序;去掉设置中帐号;
  展开notification;来电振动;启动管理;修改发送sms成功为Notify提示;去掉位置确认对话框;隐藏adb连接确认;





 
  Android初始化init.rc语言:
  由四大类声明组成:行为类(Actions);命令类(Commands);服务类(Services);选项类(Options);
  初始化语言以行为单位,由以空格间隔的语言符号组成;C风格的反斜杠转义符可以用来插入空白到语言符号;双引号也可以用来防止文本被空格分成多个语言符号;当反斜杠在行末时,作为折行符;
  以#开始(前面允许有空格)的行为注释行;
  Actions和Services隐含声明一个新的段落;所有该段落下Commands或Options的声明属于该段落;第一段落前的Commands或Options被忽略;
  Actions和Services拥有独一无二的命名;在它们之后声明相同命名的类将被当作错误并忽略;
  调试,默认情况下,init执行的程序输出的信息和错误到/dev/null;可以通过Android程序logwrapper执行你的程序,这将复位向输出错误输出到AndroidLogging系统(通过logcat访问);
  $service akmd /system/bin/logwrapper /sbin/akmd;




 
  JNI:
  System.loadLibrary("hello-jni");时会调用JNI_OnLoad();可以使用RegisterNatives注册本地方法;
  JNIEnv是一个与线程相关的变量,不同线程的JNIEnv彼此独立;sdk文档中强调了do not cache JNIEnv*,要用的时候在不同线程中再通过JavaVM *jvm的方法来获取与当前线程相关的JNIEnv*;
  JavaVM是虚拟机在JNI层的代表,在一个虚拟机进程中只有一个JavaVM,因此该进程的所有线程都可以使用这个JavaVM;
  当后台线程需要调用JNINative时,在native库中使用全局变量保存JavaVM尤为重要,这样使得后台线程能通过JavaVM获得JNIEnv;
  在C中,使用JNIEnv* env要这样,(*env)->方法名(env,参数列表);  使用JavaVM* vm要这样,(*vm)->方法名(vm,参数列表);
  在C++中,使用JNIEnv* env要这样,env->方法名(参数列表);  使用JavaVM* vm要这样,vm->方法名(参数列表);
  上面这二者的区别是,在C中必须先对env和vm间接寻址(得到的内容仍然是一个指针),在调用方法时要将env或vm传入作为第一个参数;C++则直接利用env和vm指针调用其成员;
  JavaVM接口,第一种方式,在加载动态链接库的时候,JVM会调用JNI_OnLoad(JavaVM* jvm, void* reserved)(如果定义了该函数);
  第二种方式,在native code中调用JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args)可以得到JavaVM指针;
  两种情况下,都可以用全局变量,比如JavaVM* g_jvm来保存获得的指针以便在任意上下文中使用;Android系统是利用第二种方式Invocation interface来创建JVM的;
  JNIEnv接口,当创建的线程需要获取JNIEnv*的时候,最好在刚创建的时候调用一次AttachCurrentThread,不要缓存这个JNIEnv*,每次需要的时候通过JavaVM*获取,不要忘记线程结束的时候执行DettachCurrentThread;


  从手机中备份system.img:
  $cat proc/mtd; #depress.
  $ls -l /dev/block/platform/{your_platform_name_here}/by-name; #查阅文件挂载对应设备;
  #dd if=/dev/block/mmcblk0p22 of=/sdcard/system.img bs=4096; #导出后,$file system.img;$sudo mount ***;即可;
  #dd if=/dev/block/mmcblk0p14 of=/sdcard/boot.img bs=4096; #把指定的输入文件拷贝到指定的输出文件中,并且在拷贝的过程中可以进行格式转换;
  两个特殊的设备: /dev/null,回收站/无底洞; /dev/zero,产生字符;

  Android启动过程:
  ZygoteInit.java,静态函数startSystemServer(*),启动新进程Zygote.forkSystemServer(*);forkSystemServer(*)内部调用nativeForkAndSpecialize();
  由UBOOT传入一个init参数,这个init参数制定了开机的时候运行的第一个运行的程序,默认就是init程序,这个程序就在ramdisk.img中,它的源文件在system/core/init/init.c中;入口,main()函数;
  它会调用init.rc初始化这个文件,这个文件在out/target/product/generic/root下;启动以后,会发现根目录是只读属性的,而且sdcard的owner是system,就是在这个文件中做了些手脚,可以将它改过来,实现根目录的可读写;
  android启动时首先加载的是ramdisk.img镜像,并挂载到/目录下,并进行一系列的初始化动作,包括创建各种需要的目录,初始化console,开启服务等;
  system.img是在init.rc中指定一些脚本命令,通过init.c进行解析并挂载到根目录下的/system目录下的;
  ZygoteInit.java在/frameworks/base/core/java/com/android/internal/os/目录下
  Zygote.java在/libcore/dalvik/src/main/java/dalvik/system/目录下;
  对应jni目录/dalvik/vm/native/dalvik_system_Zygote.cpp;最终调用的是linuxKernel的fork()函数;




发布了8 篇原创文章 · 获赞 7 · 访问量 12万+

猜你喜欢

转载自blog.csdn.net/liu31187/article/details/28859417
今日推荐