最近在完善创建jvm的过程,基本上与上次写的《ANDROID上创建DALVIK虚拟机与加载类》一致,此前在测试dalvik及art模式下的时候都没问题的,但最近在使用art模式下创建jvm时去遇到了问题。
使用dlopen打开了libart.so的句柄后,能正常获取到JNI_CreateJavaVM方法,但就是创建不了虚拟机,logcat中提示“InitializeSignalChain is not exported by the main executable.”。大概意思就是InitializeSignalChain没被导出,找不到相关引用的意思吧,第一反应是去找这句提示的出处,最后找到的是在以下地方,代码如下:
1 | // art/sigchainlib/sigchain_dummy.cc |
1. 用汇编编译
Android.mk1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := asm
LOCAL_ARM_MODE := arm
TARGET_CFLAGS += -mthumb-interwork
TARGET_CFLAGS += -std=gnu11
TARGET_CFLAGS += -O3
ifeq ($(TARGET_ARCH_ABI),armeabi-v7a) #depends on Application.mk
LOCAL_CFLAGS := -DHAVE_NEON=1
LOCAL_SRC_FILES += asm.s.neon #use neon mode for asm
LOCAL_ARM_NEON := true
endif
<!--more-->
#shellcode.s
LOCAL_LDLIBS += -L$(SYSROOT)/usr/lib -llog
#LOCAL_FORCE_STATIC_EXECUTABLE := true
#include $(BUILD_EXECUTABLE)
include $(BUILD_SHARED_LIBRARY)
Application.mk1
APP_ABI := armeabi-v7a # build for arm-v7
asm.s1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21.text @code section
.align 4 @align for 2^4 bytes
.thumb
.globl my_real_arm @global symbol my_real_arm
my_real_arm:
push {r1,lr} @将r1,lr入栈
push {r0-r7} @将r0至r7入栈
LDR R7, [R4,#0x14] @基址寻址,将R4的值+0x14(十进制20)作为地址,然后将该地址的值给R7
ldr r3,=10013 @赋值10013给r3
CMP R7, R3 @比较r3与r7
pop {r0-r7}
BEQ loc_ret_1
LDR R3, [R0]
LDR R2, [R4]
pop {r1,pc}
loc_ret_1:
mov r3, #0
mov r2, #1
pop {r1,pc}
然后,使用ndk-build即可。
2. 获取汇编指令对应的十六进制
因为ptrace要写入的代码不能是直接的汇编指令,而是指令对应的十进进制,故需要先用IDA找出汇编代码对应的十六进制代码才行。
然后使用HEX的视图(需要与反汇编出来的代码进行同步,右键),然后就可以知道每一个指令对应的十六进制:
3. trace
[有误!!!随后更正]
在程序运行的过程当中,可以使用PathClassLoader与DexClassLoader等加载外部的jar包或apk包,并使用反射来获取到包内的类,就可以实现程序运行时动态扩展的功能。
但如果在已经加载完一个外部包后,需要对包进行更新,且程序此时不能重启,能否简单地处理呢?
开始的时候我想既然类+加载器才可以确定一个类,那如果在加载完包并更新完包后再使用DexClassLoader,使用再使用新的类加载器去加载包里的类,那么理应来说是可以加载到新的包里面的类的。然后事实上并不成功。针对这个问题翻看了一下源码,这里作个记录。
找到类加载的代码,这里使用Class.cpp中的findClassNoInit作为例子。
more >>反射简单地使用类似如下的代码执行类中的方法
1 | TestMethod test = new TestMethod(); |
如无意外就能正确调起TestMethod中的a方法。
如前篇《DEX文件格式分析》中的类加载中一样,getDeclaredMethod的过程就是从ClassObject对象中获取到Method结构体对象,然后再将之转换成reflect对象的一个过程。
more >>Dex是android上的可执行文件类型,其包含了几乎所有代码及变量的内容,正确使用并辨识DEX文件内的内容对分析问题及使用一些较为灵活的操作方式有很大的帮助。
半成品
DEX格式定义在dalvik/libdex/DexFile.h的struct DexFile中,其由若干个部分的结构体组成,除了DexHeader文件头指定了dex文件的一些属性,包括签名,文件长度,各数据区的数目及偏移值等等外,其它部分(从DexStringId到DexClassDef部分)都是各自描述自己的内容,如DexClassDef则是描述类的定义,DexStringId则是描述字符常量的定义等。
以字符串为例,如Header中定义的1
2u4 stringIdsSize;
u4 stringIdsOff;
中,stringIdsSize为898,stringIdsOff为112,则表示stringId索引区起始于文件开始偏移112个字节的地方,字符串个数数量有898个。
more >>给模拟器准备的编译选项为full-XXX,在编译好后,生成的img镜像文件可以在源码目录下的out/target/product/generic目录下,包含imgbackup,ramdisk.img,system.img,userdata.img,但不包含内核镜像,内核镜像的生成可以按如下操作:
1. 克隆 goldfish 的内核代码(https://android.googlesource.com/kernel/goldfish.git)
2. 使用 git branch -a 查看有哪些分支,然后 checkout 喜欢的内核版本
3. 确定编译的配置
在 arch/arm/configs 目录下有很多个编译配置,给模拟器用的有两个
goldfish_armv7_defconfig
goldfish_defconfig
对于模拟器设备,构建的配置在 build/target/product下,如果需要新建自己的一个构建项,可以按如下操作:
1. 编写一个mk文件,如full.mk(可以直接复制一个然后改)
2. 对mk内的配置进行修改,修改包括设备名,以及依赖的mk,也可以选择性精简一些需要编译的项(直接注释)
3. 生成好后,在AndroidProducts.mk中添加新建mk的路径,以便在lunch的时候可以发现
4. 添加lunch_combo,在build/envsetup.sh中,编译选项,如1
add_lunch_combo full_mini-userdebug
这样,下次在source build/envsetup.sh后,就可以直接lunch full_mini-userdebug来构建编译了。
more >>最近在跟进一个问题,如下描述:
在launcher启动一个程序A(默认launchMode为standard)后,不关闭,然后退到后台,使用另一个程序B,通过getLaunchIntentForPackage(A包名)的方式获取到启动A的Intent,但启动后程序A重新创建了一个一个main activity的实例,但如果通过launcher启动则无问题;反之,如果一开始从程序B中启动程序A,则如果再通过launcher启动,则也会创建一个main activity的实例。
一开始首先考虑了以下因素造成的影响:
1. pid
在程序B启动A后,B退出,再重启B,再启动A,则没有重新创建,否定。
2. userId
考虑跟程序B(或launcher 的userid)不一样导致,使用B启动A,再重装B,再启动A,没有重新创建,否定。
3. packageName
考虑不同程序(包名)导致,使用B启动A,再修改B包名重装再启动A,没有重新创建,否定。
more >>tag:
缺失模块。
1、请确保node版本大于6.2
2、在博客根目录(注意不是yilia根目录)执行以下命令:
npm i hexo-generator-json-content --save
3、在根目录_config.yml里添加配置:
jsonContent: meta: false pages: false posts: title: true date: true path: true text: false raw: false content: false slug: false updated: false comments: false link: false permalink: false excerpt: false categories: false tags: true