dalvik虚拟机启动及运行

Android Dalvik虚拟机的启动过程源码分析 从前面的调用过程可以知道,参数array指向的是全局变量gRegJNI所描述的一个JNI方法注册函数表,其中,每一个表项都用一个RegJNIRec对象来描述,而每一个RegJNIRec对象都有一个成员变量mProc,指向一个JNI方法注册函数。这一步执行完成之后,Dalvik虚拟机的创建和初始化工作就完成了,回到前面,即AndroidRuntime类的成员函数start中,接下来就会调用AndroidRuntime类的另外一个成员函数startReg来注册Android核心类的JNI方法。 阅读详情

Zygote启动

这个称作孵化器的进程由init进程创建,之后创建了SystemServer(其中包括包管理服务,应用程序组件管理服务)。
当我们需要通过应用程序组件管理服务(ActivityManagerService)创建新进程时,会通过Socket进程间通信机制,通知Zygot进程为应用程序创建一个新的进程。

虚拟机启动

前面的Zygote在启动时,会运行AndroidRuntime类的成员函数start.
这里有个关键java的入口,好像java就是从这里开始运行的,com.android,internal.os.Zygoteinit.虚拟机也是从这里开始运行的。这个类的main退出时,也就是Zygote进程准备要退出的时候。

startVM

AndoridRuntime类里启动虚拟机的函数。
这里包含了很多启动参数,运行模式等

JNI_CreateJavaVM

这里创建了虚拟机的实例,JavaVMExt对象,创建JNI环境(JNIEnvExt对象),初始化虚拟机实例(dvmStartup)。
设置当前线程执行状态,返回调用者JavaVMExt和JNIExt,分别通过输出参数p_vm和p_env.

JavaVMExt成员变量funcTable保存了虚拟机实例的函数表。

JNIEnvExt用来在java和C/C++函数之间相互调用。并且多个线程对应的JNIEntExt组成了一个列表,第一个JINIExt表示的是主线程。

dvmCreateJNIEnv

这里会创建JNI环境,还有个JNINativeInterface的结构体,本地接口表。当我们需要在C/C++代码中 调用java函数,就要用到这个本地接口表。
findClass寻找java类,GetMethodID获得java类的成员函数,CallObjectMethod函数间接调用之。GetFeildID获得java类成员变量.当然还可以注册反注册jNI方法到java类中。

dvmStartup

初始化虚拟机
我这里关注下
1.dvmClassStartup ,用来初始化类加载器。这里是加载JAVA用的。dalvik/vm/oo/Class.c
2.dvmNativeStartup 加载so库加载 表,用来描述当前进程那些SO文件已经被加载过了。 dalvik/vm/Native.c
3.dvmInternalNativeStartup 初始化内部native函数表。

虚拟机运行

正如我们上面所得,得到JNIEnv的环境变量后,我们就可以进行函数调用了。我们通过这个结构体的成员变量function来实现函数的调用。
1.对应的java调用利用CallStaticVoidMethod(其实是由dvmCallMethodV实现的)函数执行参数clazz和methodID所描述的Java代码。
2.dvmCallMethodV这个函数其实是java和native都可以执行的,但是会通过检测method 的描述函数来判断是否是JNI方法,如果是就执行native,否则执行java函数。
3.dvmCallMethodV在执行java的时候还会调用一个dvmInterpret的函数,这个函数有几种模式,可以在初始化的时候确定。而dvmInterpret就是我们在执行Java过程中的解释器。

以Zygote进程为例,Dalvik虚拟机解释器就是以com.android.internal.os.ZygoteInit类 的静态成员函数main为入口点执行的,然后在Socket循环等待ActivityManagerService服务向它发送创建新的应用程序进程的请求。
而以Android应用程序进程为例,Dalvik虚拟机解释器就是以android.app.ActivityThread类的静态成员函数main为入口点执行,然后在消息队列上进行循环,用来等待和处理主线程的消息。

JNI注册

systemlaod——–nativelaod———-Dalvik_java_lang_runtime_nativeLoad(C++层)——-dvmaLoadNativeCode—–dlopen

然后就是native层函数对应java层的调用方式标记。是用jniRegisterNativeMethods(调用了函数表中RegisterNative)的实现。

xposed框架实现原理

为了进一步对虚拟机有较深的理解,我这里把xpose框架的各种文档也查看和阅读了下。总结成如下的图:
这里把流程图分割成了三份,作的图有点大了。
简单说xpose的框架就是核心的替换虚拟机中的执行过程中的java调用过程,如何实现这个过程?
1.是通过替换系统的app_process可执行文件实现虚拟机中函数的执行地址替换。
2.把java函数替换到native后通过调用XposedBridge.jar来实现自定义函数的调用和原函数的调用
3.具体native到java的实现大致如图2
XposeInstall是用来实现安装整个xpose框架的。
XposedMods:管理自己开发的插件app.
图1

图2

图3
这里含有个关键的函数hookMethodNative,这个函数提供一个方法对象利用Java的Reflection机制来对内置方法覆写,也就是过程2.
不过我看了最新版的xpose源码,很多函数的名字改了,不过看了下原理差不多,根据上面的流程很容易看懂就不说了。

ART模拟器的简单介绍

dalvik和ART是通过标志来判断和切换的。运行的大致过程都是从Androidruntime:start开始的
art虚拟机不一定会利用解释器,原理就是翻译dex成本地机器码,然后直接调用即可。(因为android本身是基于linux系统的)
art生成的oat文件本身包含dex部分和elf可执行部分,通过一定的对应关系实现调用。其实这也可以算是一种解释方式。映射式的解释方式。
oat是在安装的时候生成的, 运行时包含两种指令,dex指令和本地指令,会分别通过解释模式和本地模式执行。
这里写图片描述

小结

研究了一段时间android的虚拟机,感觉光从代码角度来讲,很容易看的云里雾里。主要原因如下:
代码对于计算机来讲无非就是数字和字符形式的字节流。而人类为了设计和阅读代码必须要把代码抽象成具体的事物,便于描述和记录。但我们设计的东西很多其实并没有十分清晰的现实事物的对应,比如虚拟机。在现实中就没这种事物,那么就只能把抽象的东西进行进一步的分割具体化。比方说,孵化器,解释器,线程池等,然而这些东西还是不够具体,就只能更进一步的具体化解释。这样多解释几次反而把程序的本质给解释的更复杂了。
所以,阅读代码就很容易产生困惑。为了较为清晰的解决这些困惑,我个人觉得阅读代码千万不能毫无侧重点。这里可能要把握两点:
1.就是对象初始化的状态,这个是我们程序描述的对象的一种状态,不管任何对象,如何抽象,都会描述为某一种状态。(包括成员变量中的各种值,定义,结构等)
2.对象接口方法对状态的更改,及一种状态到另一种状态的改变。(主要就是成员变量,结构,定义的状态改变)
其实不管抽象成什么东西,不外乎就是这两种东西。
另外学习代码最好要找到自己需求的逻辑主线,我这里阅读的主线就是虚拟机对于java类加载过程,和natvie方法注册及解析过程的还原。

Xposed框架原理深入研究
http://blog.youkuaiyun.com/zhangmiaoping23/article/details/52572447

Dalvik虚拟机的启动过程分析
http://blog.youkuaiyun.com/luoshengyang/article/details/8885792

Dalvik虚拟机的运行过程分析
http://blog.youkuaiyun.com/luoshengyang/article/details/8914953

Dalvik虚拟机JNI方法的注册过程分析
http://blog.youkuaiyun.com/luoshengyang/article/details/8923483

Android Hook框架Xposed原理与源代码分析
http://blog.youkuaiyun.com/wxyyxc1992/article/details/17320911

Android ART运行时无缝替换Dalvik虚拟机的过程分析 - 优快云博客
http://blog.youkuaiyun.com/luoshengyang/article/details/18006645

Dalvik虚拟机简要介绍 NULL 博文链接:https://hwy1782.iteye.com/blog/1860810 立即下载

相关推荐

STM32F030F4P6 ADC多通道定时器触发DMA搬运

主函数中等待转换完成的标志位,然后打印出来。ADC回调函数中将数值赋值给变量。配置定时器1s读一次。

qq_24426625的博客 1356

dalvik启动过程

从Zygote进程启动过程分析过程中,我们知道,dalvik虚拟机的启动过程是从AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv)函数开始的,详细时序图如下: 下面我们来逐步详细地分析一下每个步骤。 1.startVm(AndroidRuntime.cpp) /* * Start the Dalvik Virtual

成长的记忆 3773

树莓派5搭建ROS1开发环境:从系统安装到环境变量配置

本文详细指导如何在树莓派5上搭建ROS1开发环境。针对树莓派OS非标准安装路径导致的常见CMake报错问题,提供了从系统烧录、一键安装ROS到关键环境变量配置的完整解决方案,确保工作空间能成功编译,助力机器人项目开发。

weixin_29159127的博客 385

dalvik虚拟机执行流程解析

Android framework 139

强化学习-马尔可夫模型

前文提到了强化学习源自马尔可夫决策过程,本文从马尔可夫概念入手,讲解和马尔可夫有关的模型和概念。在马尔科夫决策过程中,我们有一个智能体,它在一个马尔科夫过程中进行决策,每次决策都会导致状态的转移和获得即时奖励。智能体的目标是通过选择动作来最大化未来奖励的期望值。通常马尔科夫决策过程是个五元组:SAPRγSAPRγS 表示状态集合,代表智能体可能处于的所有状态。A 表示动作集合,代表智能体可以采取的所有动作。

君子之学必日新,日新者日进也。不日新者必日退,未有不进而不退者 8062

高级技能-高可用和容灾-两地三中心、异地多活架构

两地三中心和异地多活是当前主流的跨地域高可用架构方案。两地三中心通过生产中心、同城灾备和异地灾备的组合,提供多级容灾能力,适合对数据安全要求高的行业。异地多活则采用单元化设计,多个站点同时服务,提升资源利用率,但需解决网络延迟、数据冲突等挑战。两种架构在RTO/RPO、一致性、改造成本等方面各具特点,企业应根据业务规模、一致性要求和预算进行选择,可考虑从同城双活起步,逐步向异地多活演进。混合架构可能是平衡容灾与多活的务实方案。

zhongjianfeng100的博客 169

Dalvik VM start up process

Dalvik VM的启动过程解析 Dalvik 虚拟机的启动要从android另一个著名的模块,Zygote,说起。   我们知道android系统中,每一个java应用被设计成可以运行在一个单独的Linux进程中。而每个该进程都包含一个运行中的dalvik虚拟机实例,用来执行该应用中的java字节码。很多java基础类(比如,java.lang.*)和一些系统级的共享性资源

琪妙的Android世界 7467

芒果YOLOv8改进52:主干Backbone篇之GhostNetV2:提出原创GhostNetV2 架构升级版:引入长距离注意力机制增强廉价操作,构建更强端侧轻量型骨干,打造高效轻量级检测器

长距离注意力机制增强廉价操作,打造轻量级检测器

包括YOLOv5、YOLOv7、YOLOv8等模型改进 1611

Dalvik虚拟机启动全程解析

0x01:启动点 我们知道,Android基于linux,linux的第一个进程为init,它启动别的进程,在Android中,它启动了zygote: service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server class main socket zygo...

随手记两笔 614

详解AUTOSAR:AUTOSAR架构中的配置文件(拓展篇—7)

查看AUTOSAR代码包时会发现一些这样格式的文件:xxx_PBcfg.c、xxx_Lcfg.c和xxx_Cfg.h,本篇博文讲一讲这几个配置文件的作用和特点。

不脱发的程序猿 2147

电容式三点式振荡电路/电感式三点振荡电路基础知识及Multisim电路仿真

摘要:三极管振荡电路利用放大特性与正反馈实现自激振荡,需满足巴克豪森条件(增益≥1,相位匹配)。核心由放大级、反馈网络、选频网络和稳幅环节构成。主要分为三类:1)LC/RC正弦波振荡电路(如电容三点式、电感三点式),输出高频/低频正弦波;2)多谐振荡电路,通过电容充放电产生方波;3)张弛振荡电路,生成锯齿波等。设计需关注相位匹配、增益控制和元件适配。LC振荡频率由谐振参数决定,RC振荡由时间常数控制。稳幅机制通过非线性或主动元件维持等幅输出。该电路在信号发生、时钟源等领域有广泛应用。

XU157303764的博客 2038

linux运行dalvik,Dalvik——基本Dalvik VM调用

在Android设备上,dalvik vm通常都被嵌入到android应用框架里执行,也可以直接运行vm,就像你要在你桌面系统运行虚拟机一样。在编译完java源码后,转换并整合.class文件到.dex文件然后将它push到设备。这儿是个简单的例子:% echo 'class Foo {'\> 'public static void main(String[] args) {'\> '...

weixin_29074409的博客 794

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

Dalvik虚拟机和ART虚拟机

Dalvik虚拟机与Java虚拟机共享有差不多的特性,例如,它们都是解释执行,并且支持即时编译(JIT)、垃圾收集(GC)、Java本地方法调用(JNI)和Java远程调试协议(JDWP)等,差别在于两者执行的指令集是不一样的,并且前者的指令集是基本寄存器的,而后者的指令集是基于堆栈的。Dalvik虚拟机起源于Apache Harmony项目,后者是由Apache软件基金会主导的,目标是实现一个独立的、兼容JDK 5的虚拟机,并根据Apache License v2发布。

博客 1061

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

5分钟了解Android虚拟机Dalvik和ART,让手机告别卡顿!

Android虚拟机一.Dalvik虚拟机1.DVM与JVM的主要区别1)架构不同2)执行字节码不同3)DVM的预加载-共享机制2.DVM的运行时堆1)Zygote Space2)Card Table3)Heap Bitmap4)Mark Stack3.DVM的GC日志1)格式2)引起GC的原因二.ART虚拟机1.ART和DVM的区别1)DVM采用JIT编译,ART采用AOT编译。2)DVM为32...

LeeDuoZuiShuai的博客 1954

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

Dalvik虚拟机相关的可执行程序

Dalvik虚拟机相关的可执行程序 在Android源码中,大家会发现好几处和Dalvik这个概念相关的可执行程序,正确区分这些可执行程序的区别将有助于理解Framework内部结构。这些可执行程序的名称和源码路径如表9-1所示。     下面将分别介绍这些可执行程序的作

博文视点(北京)官方博客 1208

Android本地服务的启动 - zygote服务及Dalvik环境启动

通过上一节Android init进程启动的分析可知,init进程在启动过程中,解析并处理了init.rc和init.hardware.rc两个初始化脚本文件,在两个初始化脚本文件里,定义了一系列的service section,这些service在boot触发器下,通过class_start default依次启动,其过程总结如下:     1. init 解析init.rc     2

mr_raptor的专栏 7138

安卓逆向学习----Dalvik虚拟机

Dalvik名字来源于其作者祖先居住的小村庄,老外喜欢起这种名字,类似的还有ubuntu、Kali,虽说现在使用ART取代了Dalvik,但是感觉简单学习一下还是有用的。 一、.与java虚拟机对比 Java虚拟机解析class文件,Dalvik虚拟机解析dex(dalvik executable)文件 android SDK 的dx工具可以将java字节码转换为Dalvik字节码,对jav......

qq_34418601的博客 1220

JAVA虚拟机、Dalvik虚拟机和ART虚拟机

从Android5.0开始废弃了Dalvik,全面推行ART。 Dalvik与ART的区别 (1)在Dalvik下,应用每次运行都需要通过即时编译器(JIT)将字节码转换为机器码,即每次都要编译加运行,这虽然会使安装过程比较快,但是会拖慢应用以后每次启动的效率。而在ART环境中,应用在第一次安装的时候,字节码就会预编译(AOT)成机器码,这样的话,虽然设备和应用的首次启动(安装慢了)会变慢,但是以后每次启动执行的时候,都可以直接运行,因此运行效率会提高。 (2)ART占用空间比Dalvik大(字节码.

u010783226的专栏 722

Dalvik启动、初始化、执行java、执行jni思维导图

相关文章链接: Dalvik虚拟机的启动过程分析 http://blog.youkuaiyun.com/luoshengyang/article/details/8885792 Dalvik虚拟机的运行过程分析 http://blog.youkuaiyun.com/luoshengyang/article/details/8914953 Dalvik虚拟机JNI方法的注册过程分析 http:...

weixin_30699235的博客 78

Android ART运行时无缝替换Dalvik虚拟机的过程分析

Android 4.4发布了一个ART运行时,准备用来替换掉之前一直使用的Dalvik虚拟机,希望籍此解决饱受诟病的性能问题。老罗不打算分析ART的实现原理,只是很有兴趣知道ART是如何无缝替换掉原来的Dalvik虚拟机的。毕竟在原来的系统中,大量的代码都是运行在Dalvik虚拟机里面的。开始觉得这个替换工作是挺复杂的,但是分析了相关代码之后,发现思路是很清晰的。本来就详细分析这个无缝的替换过程。

老罗的Android之旅 9万+

ART和Dalvik区别

ART和Dalvik区别 Art上应用启动快,运行快,但是耗费更多存储空间,安装时间长,总的来说ART的功效就是"空间换时间"。 ART: Ahead of Time Dalvik: Just in Time 什么是Dalvik:Dalvik是Google公司自己设计用于Android平台的Java虚拟机。Dalvik虚拟机是Google等厂商合作开发的Android移动设备

it_yangkun的博客 497

Dalvik虚拟机、Java虚拟机与ART虚拟机

一、Java虚拟机 1. Java的是Java字节码。 传统的Java程序经过编译,生成Java字节码保存在class文件中,Java虚拟机通过解码class文件中的内容来运行程序。 2. Java虚拟机基于栈架构。 程序在运行时虚拟机需要频繁的从栈上读取或写入数据,这个过程需要更多的指令分派与内存访问次数,会耗费不少CPU时间。 二、Dalvik虚拟机(Android 4....

YSoul的博客 7338

Dalvik虚拟机源码初探

Dalvik虚拟机JNI方法的注册过程分析 这些Bridage函数实际上仍然不是直接调用地调用JNI方法的, 这是因为Dalvik虚拟机是可以运行在各种不同的平台之上,而每一种平台可能都定义有自己的一套函数调用规范, 也就是所谓的ABI(Application Binary Interface),这是一个API(Application Programming Interface)不同的概念。 ABI是在二进制级别上定义的一套函数调用规范, 例如参数是通过寄存器来传递还是堆栈来传递,而API定义是一个应

疾风剑豪 634
上一篇: 看雪CTF2017秋季赛第五题分析
下一篇: dex加载及替换
inquisiter
博客等级 码龄10年 374粉丝 228原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值