一、前言
最近在弄系统定制功能的时候(比如打印File构造函数的参数),需要修改libcore中的核心代码并打印日志输出。虽然Android提供了android.utils.Log日志工具类,但是不能在android java层的核心库libcore中调用。虽然可以使用System.out输出,但是不能满足需求。所以参考android.utils.Log的实现方式移植导libcore核心库中供整个安卓系统java层调用。
二、移植Log的方式讨论
将android.utils.Log移植到libcore中可以两种方式:
(1)、在现有的类中添加方法,并在native追加对应的方法,这种方式相对简单
比如java.lang.System中添加相应的方法,在对应System.c中添加对应的jni方法。
(2)、在libcore中添加新的接口类,并实现native的方法,这种方式相对复杂一点
本着学习研究的心态,以下选方案2来操作。
三、移植过程
1.添加java.lang.XLog日志类
(1).创建java.lang.XLog类
在libcore路径位置:
/home/qiang/lineageOs/libcore/ojluni/src/main/java/java/lang
目录下新建XLog文件,如下所示:
qiang@ubuntu:~/lineageOs/libcore/ojluni/src/main/java/java/lang$ ls -la XLog.java
-rwxrwxrwx 1 qiang qiang 2124 1月 19 20:50 XLog.java
(2).参考android.utils.Log的实现添加XLog日志方法
此处只添加几个常用的方法,添加之后核心代码如下所示:
...省略
public static native int println_native(int bufID, int priority, String tag, String msg);
public static int d(@Nullable String tag, @NonNull String msg) {
return println_native(LOG_ID_MAIN, DEBUG, tag, msg);
}
...省略
(3)、将XLog.java文件添加到编译文件链
在/home/qiang/lineageOs/libcore/penjdk_java_files.bp文件中加入XLog.java到编译文件链。如下所示:
// Classes which are part of the public API, except where classes and
// members are hidden using @hide javadoc tags.
filegroup {
name: "openjdk_javadoc_files",
srcs: [
...省略
"ojluni/src/main/java/java/lang/System.java",
///ADD START
"ojluni/src/main/java/java/lang/XLog.java",
///ADD END
"ojluni/src/main/java/java/lang/ThreadDeath.java",
...省略
],
}
...省略
2.XLog.java jni实现
(1).在libcore native层添加XLog.c
XLog.c主要是实现XLog的native方法。XLog.c创建之后如下:
qiang@ubuntu:~/lineageOs/libcore/ojluni/src/main/native$ pwd
/home/qiang/lineageOs/libcore/ojluni/src/main/native
qiang@ubuntu:~/lineageOs/libcore/ojluni/src/main/native$ ls -la XLog.c
-rwxrwxr-x 1 qiang qiang 9678 1月 20 00:13 XLog.c
参考android_util_Log.cpp中println_native实现方式,在XLog.c中添加如下实现:
static jint java_lang_XLog_println_native(JNIEnv* env, jobject clazz,
jint bufID, jint priority, jstring tagObj, jstring msgObj)
{
const char* tag = NULL;
const char* msg = NULL;
if (msgObj == NULL) {
JNU_ThrowNullPointerException(env, "println needs a message");
return -1;
}
if (bufID < 0 || bufID >= LOG_ID_MAX) {
JNU_ThrowNullPointerException(env, "bad bufID");
return -1;
}
if (tagObj != NULL)
tag = (*env)->GetStringUTFChars(env,evn,tagObj, NULL);
msg = (*env)->GetStringUTFChars(env,msgObj, NULL);
int res = __android_log_buf_write(bufID, (android_LogPriority)priority, tag, msg);
if (tag != NULL)
(*env)->ReleaseStringUTFChars(env,tagObj, tag);
(*env)->ReleaseStringUTFChars(env,msgObj, msg);
return res;
}
在XLog.c中添加register_java_lang_XLog方法来注册XLog的jni的方法。如下所示:
void register_java_lang_XLog(JNIEnv* env) {
jniRegisterNativeMethods(env, "java/lang/XLog", gMethods, NELEM(gMethods));
}
(2).OnLoad.cpp中声明和调用register_java_lang_XLog
OnLoad.cpp文件路径如下:
libcore/ojluni/src/main/native/OnLoad.cpp
在OnLoad.cpp中添加register_java_lang_XLog方法的声明和调用。如下所示:
...省略
///ADD START
extern "C" void register_java_lang_XLog(JNIEnv* env);
///ADD END
...省略
extern "C" JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void*) {
...省略
///ADD START
register_java_lang_XLog(env);
///ADD END
...省略
}
...省略
(3).Android.bp中添加XLog.c文件到编译文件中
在文件"/home/qiang/Desktop/test/sourcecode/libcore/ojluni/src/main/native/Android.bp"中添加XLog.c到编译文件中。
添加之后如下:
filegroup {
name: "libopenjdk_native_srcs",
srcs: [
...省略
///ADD START
"XLog.c",
///ADD END
...省略
],
}
四、编译更新系统api
由于向系统加了新的接口,需要执行如下命令更新系统api:
source build/envsetup.sh
make update-api
五、测试验证
我在java.io.File构造函数中调用XLog打印文件。如下所示:
编译系统刷机,终端查看日志:
C:\Users\Qiang>adb logcat FILE:D *:s
--------- beginning of system
--------- beginning of main
01-20 19:28:24.077 1373 1518 D FILE : File==>/system/app/SecurityManager/lib/arm64/wrap.sh
01-20 19:28:24.087 921 921 D FILE : File==>/proc/self/task
01-20 19:28:24.173 4704 4704 D FILE : File==>/system/etc/security/cacerts
01-20 19:28:24.173 4704 4704 D FILE : File==>/data/misc/keychain
01-20 19:28:24.214 4704 4704 D FILE : File==>/data/user/0/com.android.securitymanager
01-20 19:28:24.214 4704 4704 D FILE : File==>/data/user_de/0/com.android.securitymanager
01-20 19:28:24.214 4704 4704 D FILE : File==>/data/user/0/com.android.securitymanager
01-20 19:28:24.223 4704 4704 D FILE : File==>/system/app/SecurityManager/SecurityManager.apk
01-20 19:28:24.223 4704 4704 D FILE : File==>/system/app/SecurityManager/SecurityManager.apk
01-20 19:28:24.229 4704 4704 D FILE : File==>/system/app/SecurityManager/lib/arm64
01-20 19:28:24.229 4704 4704 D FILE : File==>/system/lib64
01-20 19:28:24.229 4704 4704 D FILE : File==>/system/product/lib64
01-20 19:28:24.229 4704 4704 D FILE : File==>/system/vendor/lib64
01-20 19:28:24.229 4704 4704 D FILE : File==>/system/lib64
01-20 19:28:24.230 4704 4704 D FILE : File==>/system/product/lib64
完整修改的代码关注公众号之后发送消息"002"下载。
上一篇玩转安卓10源码开发定制(18)编译Windows平台adb和fastboot工具
专注安卓系统、安卓ndk开发、安卓应用安全和逆向分析相关等IT知识分享,系统定制、frida、xposed(sandhook、edxposed)系统集成、加固、脱壳等等。微信搜索公众号"QDOIRD88888"或者扫描以下二维码关注公众号。第一时间接收更新文章。