ubuntu 20.04系统AOSP(Android 11)集成Frida

ubuntu 20.04系统AOSP(Android 11)集成Frida
参考 ubuntu 20.04编译Android 11源代码&模拟器 完成Android 11源代码的编译工作,保证能编译通过。

想自己手工编译Frida源代码的话,请参照下面:

$ git clone https://github.com/frida/frida.git

$ cd frida

$ make

$ export ANDROID_NDK_ROOT=/data/Android/android-sdk-linux/ndk/22.0.6917172

$ sudo apt-get install npm

$ sudo apt install python3-pip

$ pip3 install colorama prompt-toolkit pygments

$ rm -rf build

$ make core-android-x86_64

$ make core-android-x86

最后生成的文件在 build/frida-android-x86 build/frida-android-x86_64

如果需要调整编译参数,在releng/setup-env.sh中进行调整 比如: meson_common_flags=“[‘-g’]”

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
$ git clone https://github.com/frida/frida.git

$ cd frida

$ make

$ export ANDROID_NDK_ROOT=/data/Android/android-sdk-linux/ndk/22.0.6917172

$ sudo apt-get install npm

$ sudo apt install python3-pip

$ pip3 install colorama prompt-toolkit pygments

$ rm -rf build

$ make core-android-x86_64

$ make core-android-x86

最后生成的文件在 build/frida-android-x86 build/frida-android-x86_64

如果需要调整编译参数,在releng/setup-env.sh中进行调整 比如: meson_common_flags=“[‘-g’]”

如果想直接下载对应版本的Frida库并存放到已经编译过的库位置,由于64位系统需要兼容32位应用,因此需要安装两个版本的动态库:

$ cd ~/AndSrc/aosp/

$ cd out/target/product/generic_x86_64/system/lib64

$ wget https://github.com/frida/frida/releases/download/14.2.2/frida-gadget-14.2.2-android-x86_64.so.xz

$ xz -d frida-gadget-14.2.2-android-x86_64.so.xz

Android要求动态库必须是lib开头

$ mv frida-gadget-14.2.2-android-x86_64.so libfrida-gadget-14.2.2-android-x86_64.so

$ cd ~/AndSrc/aosp/

$ cd out/target/product/generic_x86_64/system/lib

$ wget https://github.com/frida/frida/releases/download/14.2.2/frida-gadget-14.2.2-android-x86.so.xz

$ xz -d frida-gadget-14.2.2-android-x86.so.xz

Android要求动态库必须是lib开头

$ mv frida-gadget-14.2.2-android-x86.so libfrida-gadget-14.2.2-android-x86.so
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
$ cd ~/AndSrc/aosp/

$ cd out/target/product/generic_x86_64/system/lib64

$ wget https://github.com/frida/frida/releases/download/14.2.2/frida-gadget-14.2.2-android-x86_64.so.xz

$ xz -d frida-gadget-14.2.2-android-x86_64.so.xz

Android要求动态库必须是lib开头

$ mv frida-gadget-14.2.2-android-x86_64.so libfrida-gadget-14.2.2-android-x86_64.so

$ cd ~/AndSrc/aosp/

$ cd out/target/product/generic_x86_64/system/lib

$ wget https://github.com/frida/frida/releases/download/14.2.2/frida-gadget-14.2.2-android-x86.so.xz

$ xz -d frida-gadget-14.2.2-android-x86.so.xz

Android要求动态库必须是lib开头

$ mv frida-gadget-14.2.2-android-x86.so libfrida-gadget-14.2.2-android-x86.so
创建Frida Gadget库的配置文件

$ cd ~/AndSrc/aosp/

$ cd out/target/product/generic_x86_64/system/lib64

$ touch libfrida-gadget-14.2.2-android-x86_64.config.so

$ cd ~/AndSrc/aosp/

$ cd out/target/product/generic_x86_64/system/lib

$ touch libfrida-gadget-14.2.2-android-x86.config.so
1
2
3
4
5
6
7
8
9
10
11
$ cd ~/AndSrc/aosp/

$ cd out/target/product/generic_x86_64/system/lib64

$ touch libfrida-gadget-14.2.2-android-x86_64.config.so

$ cd ~/AndSrc/aosp/

$ cd out/target/product/generic_x86_64/system/lib

$ touch libfrida-gadget-14.2.2-android-x86.config.so
里面的配置内容如下:

{
“interaction”: {
“type”: “listen”,
“address”: “127.0.0.1”,
“port”: 27042,
“on_load”: “resume”
}
}
1
2
3
4
5
6
7
8
{
“interaction”: {
“type”: “listen”,
“address”: “127.0.0.1”,
“port”: 27042,
“on_load”: “resume”
}
}
观察Frida源代码,发现在 frida-core/lib/gadget/gadget-glue.c中配置了lib库的入口函数

frida-core/lib/gadget/gadget-glue.cC++
attribute ((constructor)) static void
frida_on_load (void)
{
frida_gadget_load (NULL, NULL, NULL);
}
1
2
3
4
5
attribute ((constructor)) static void
frida_on_load (void)
{
frida_gadget_load (NULL, NULL, NULL);
}
这就意味着只要使用dlopen加载frida-gadget,我们就能实现对于指定应用的Hook。

我们只需要监听子进程,不需要在Zygote中加载,因此只需要在源代码 frameworks/base/core/jni/com_android_internal_os_Zygote.cpp 的com_android_internal_os_Zygote_nativeForkAndSpecialize函数中增加加载代码:

/*
 * 在虚拟机,系统框架初始化完成之后,加载frida框架
 * 需要增加头文件的引用 #include <dlfcn.h>
 */

#if defined(x86_64) || defined(i386)
{
#if defined(x86_64)
#define FRIDA_LIB “/system/lib64/libfrida-gadget-14.2.2-android-x86_64.so”
#else
#define FRIDA_LIB “/system/lib/libfrida-gadget-14.2.2-android-x86.so”
#endif
const char name = env->GetStringUTFChars(nice_name, 0);
void
frida = dlopen(FRIDA_LIB, RTLD_NOW);
if(NULL == frida) {
ALOGE(“(%s) load frida-gadget(%s) failed, err= %d\n”, name, FRIDA_LIB, errno);
} else {
ALOGI(“(%s) load frida-gadget(%s) success\n”, name, FRIDA_LIB);
}
env->ReleaseStringUTFChars(nice_name, name);
}
#endif
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/*
* 在虚拟机,系统框架初始化完成之后,加载frida框架
* 需要增加头文件的引用 #include <dlfcn.h>
*/
#if defined(x86_64) || defined(i386)
{
#if defined(x86_64)
#define FRIDA_LIB “/system/lib64/libfrida-gadget-14.2.2-android-x86_64.so”
#else
#define FRIDA_LIB “/system/lib/libfrida-gadget-14.2.2-android-x86.so”
#endif
const char name = env->GetStringUTFChars(nice_name, 0);
void
frida = dlopen(FRIDA_LIB, RTLD_NOW);
if(NULL == frida) {
ALOGE(“(%s) load frida-gadget(%s) failed, err= %d\n”, name, FRIDA_LIB, errno);
} else {
ALOGI(“(%s) load frida-gadget(%s) success\n”, name, FRIDA_LIB);
}
env->ReleaseStringUTFChars(nice_name, name);
}
#endif
具体添加位置如下:

frameworks/base/core/jni/com_android_internal_os_Zygote.cppC++
static jint com_android_internal_os_Zygote_nativeForkAndSpecialize(
JNIEnv* env, jclass, jint uid, jint gid, jintArray gids,
jint runtime_flags, jobjectArray rlimits,
jint mount_external, jstring se_info, jstring nice_name,
jintArray managed_fds_to_close, jintArray managed_fds_to_ignore, jboolean is_child_zygote,
jstring instruction_set, jstring app_data_dir, jboolean is_top_app,
jobjectArray pkg_data_info_list, jobjectArray whitelisted_data_info_list,
jboolean mount_data_dirs, jboolean mount_storage_dirs) {
jlong capabilities = CalculateCapabilities(env, uid, gid, gids, is_child_zygote);

if (UNLIKELY(managed_fds_to_close == nullptr)) {
  ZygoteFailure(env, "zygote", nice_name, "Zygote received a null fds_to_close vector.");
}

std::vector<int> fds_to_close =
    ExtractJIntArray(env, "zygote", nice_name, managed_fds_to_close).value();
std::vector<int> fds_to_ignore =
    ExtractJIntArray(env, "zygote", nice_name, managed_fds_to_ignore)
        .value_or(std::vector<int>());

std::vector<int> usap_pipes = MakeUsapPipeReadFDVector();

fds_to_close.insert(fds_to_close.end(), usap_pipes.begin(), usap_pipes.end());
fds_to_ignore.insert(fds_to_ignore.end(), usap_pipes.begin(), usap_pipes.end());

fds_to_close.push_back(gUsapPoolSocketFD);

if (gUsapPoolEventFD != -1) {
  fds_to_close.push_back(gUsapPoolEventFD);
  fds_to_ignore.push_back(gUsapPoolEventFD);
}

if (gSystemServerSocketFd != -1) {
    fds_to_close.push_back(gSystemServerSocketFd);
    fds_to_ignore.push_back(gSystemServerSocketFd);
}

pid_t pid = ForkCommon(env, false, fds_to_close, fds_to_ignore, true);

if (pid == 0) {
  SpecializeCommon(env, uid, gid, gids, runtime_flags, rlimits,
                   capabilities, capabilities,
                   mount_external, se_info, nice_name, false,
                   is_child_zygote == JNI_TRUE, instruction_set, app_data_dir,
                   is_top_app == JNI_TRUE, pkg_data_info_list,
                   whitelisted_data_info_list,
                   mount_data_dirs == JNI_TRUE,
                   mount_storage_dirs == JNI_TRUE);

/*
 * 在虚拟机,系统框架初始化完成之后,加载frida框架
 * 需要增加头文件的引用 #include <dlfcn.h>
 */

#if defined(x86_64) || defined(i386)
{
#if defined(x86_64)
#define FRIDA_LIB “/system/lib64/libfrida-gadget-14.2.2-android-x86_64.so”
#else
#define FRIDA_LIB “/system/lib/libfrida-gadget-14.2.2-android-x86.so”
#endif
const char name = env->GetStringUTFChars(nice_name, 0);
void
frida = dlopen(FRIDA_LIB, RTLD_NOW);
if(NULL == frida) {
ALOGE(“(%s) load frida-gadget(%s) failed, err= %d\n”, name, FRIDA_LIB, errno);
} else {
ALOGI(“(%s) load frida-gadget(%s) success\n”, name, FRIDA_LIB);
}
env->ReleaseStringUTFChars(nice_name, name);
}
#endif

}
return pid;

}
1
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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
static jint com_android_internal_os_Zygote_nativeForkAndSpecialize(
JNIEnv* env, jclass, jint uid, jint gid, jintArray gids,
jint runtime_flags, jobjectArray rlimits,
jint mount_external, jstring se_info, jstring nice_name,
jintArray managed_fds_to_close, jintArray managed_fds_to_ignore, jboolean is_child_zygote,
jstring instruction_set, jstring app_data_dir, jboolean is_top_app,
jobjectArray pkg_data_info_list, jobjectArray whitelisted_data_info_list,
jboolean mount_data_dirs, jboolean mount_storage_dirs) {
jlong capabilities = CalculateCapabilities(env, uid, gid, gids, is_child_zygote);

if (UNLIKELY(managed_fds_to_close == nullptr)) {
  ZygoteFailure(env, "zygote", nice_name, "Zygote received a null fds_to_close vector.");
}

std::vector<int> fds_to_close =
    ExtractJIntArray(env, "zygote", nice_name, managed_fds_to_close).value();
std::vector<int> fds_to_ignore =
    ExtractJIntArray(env, "zygote", nice_name, managed_fds_to_ignore)
        .value_or(std::vector<int>());

std::vector<int> usap_pipes = MakeUsapPipeReadFDVector();

fds_to_close.insert(fds_to_close.end(), usap_pipes.begin(), usap_pipes.end());
fds_to_ignore.insert(fds_to_ignore.end(), usap_pipes.begin(), usap_pipes.end());

fds_to_close.push_back(gUsapPoolSocketFD);

if (gUsapPoolEventFD != -1) {
  fds_to_close.push_back(gUsapPoolEventFD);
  fds_to_ignore.push_back(gUsapPoolEventFD);
}

if (gSystemServerSocketFd != -1) {
    fds_to_close.push_back(gSystemServerSocketFd);
    fds_to_ignore.push_back(gSystemServerSocketFd);
}

pid_t pid = ForkCommon(env, false, fds_to_close, fds_to_ignore, true);

if (pid == 0) {
  SpecializeCommon(env, uid, gid, gids, runtime_flags, rlimits,
                   capabilities, capabilities,
                   mount_external, se_info, nice_name, false,
                   is_child_zygote == JNI_TRUE, instruction_set, app_data_dir,
                   is_top_app == JNI_TRUE, pkg_data_info_list,
                   whitelisted_data_info_list,
                   mount_data_dirs == JNI_TRUE,
                   mount_storage_dirs == JNI_TRUE);

/*
 * 在虚拟机,系统框架初始化完成之后,加载frida框架
 * 需要增加头文件的引用 #include <dlfcn.h>
 */

#if defined(x86_64) || defined(i386)
{
#if defined(x86_64)
#define FRIDA_LIB “/system/lib64/libfrida-gadget-14.2.2-android-x86_64.so”
#else
#define FRIDA_LIB “/system/lib/libfrida-gadget-14.2.2-android-x86.so”
#endif
const char name = env->GetStringUTFChars(nice_name, 0);
void
frida = dlopen(FRIDA_LIB, RTLD_NOW);
if(NULL == frida) {
ALOGE(“(%s) load frida-gadget(%s) failed, err= %d\n”, name, FRIDA_LIB, errno);
} else {
ALOGI(“(%s) load frida-gadget(%s) success\n”, name, FRIDA_LIB);
}
env->ReleaseStringUTFChars(nice_name, name);
}
#endif

}
return pid;

}
编译并重新生成系统镜像:

$ cd ~/AndSrc/aosp/

$ export USE_CCACHE=1

$ source build/envsetup.sh

$ lunch aosp_x86_64-eng

$ cd frameworks/base

$ mmm

如果只是替换镜像里面的so文件,不修改源代码,则需要执行 make snod 才能重新生成镜像

cd ~/AndSrc/aosp/

make snod

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$ cd ~/AndSrc/aosp/

$ export USE_CCACHE=1

$ source build/envsetup.sh

$ lunch aosp_x86_64-eng

$ cd frameworks/base

$ mmm

如果只是替换镜像里面的so文件,不修改源代码,则需要执行 make snod 才能重新生成镜像

cd ~/AndSrc/aosp/

make snod

运行镜像
选择system-qemu.img和vendor-qemu.img,这两个镜像是专门为qemu运行制作的,如果选择system.img 和vendor.img,则avd运行失败。

$ cd ~/AndSrc/aosp

$ export ANDROID_BUILD_TOP=~/AndSrc/aosp

$ export PATH= P A T H : PATH: PATH:ANDROID_BUILD_TOP/out/host/linux-x86/bin

$ export ANDROID_SWT=$ANDROID_BUILD_TOP/out/host/linux-x86/framework

$ export ANDROID_PRODUCT_OUT=$ANDROID_BUILD_TOP/out/target/product/generic_x86_64

$ ./prebuilts/android-emulator/linux-x86_64/emulator -system ./out/target/product/generic_x86_64/system-qemu.img -data ./out/target/product/generic_x86_64/data.img -ramdisk ./out/target/product/generic_x86_64/ramdisk-qemu.img -vendor ./out/target/product/generic_x86_64/vendor-qemu.img -verbose -show-kernel
1
2
3
4
5
6
7
8
9
10
11
$ cd ~/AndSrc/aosp

$ export ANDROID_BUILD_TOP=~/AndSrc/aosp

$ export PATH= P A T H : PATH: PATH:ANDROID_BUILD_TOP/out/host/linux-x86/bin

$ export ANDROID_SWT=$ANDROID_BUILD_TOP/out/host/linux-x86/framework

$ export ANDROID_PRODUCT_OUT=$ANDROID_BUILD_TOP/out/target/product/generic_x86_64

$ ./prebuilts/android-emulator/linux-x86_64/emulator -system ./out/target/product/generic_x86_64/system-qemu.img -data ./out/target/product/generic_x86_64/data.img -ramdisk ./out/target/product/generic_x86_64/ramdisk-qemu.img -vendor ./out/target/product/generic_x86_64/vendor-qemu.img -verbose -show-kernel
上面运行起来的镜像是从~/AndSrc/aosp/out/debug/target/product/generic/hardware-qemu.ini即可读取配置信息的,但是这个文件直接修改无效,我们如果需要修改参数,只能从启动参数中设置。
比如我们如果需要增大内存,开启GPU的支持,则执行如下命令:

$ ./prebuilts/android-emulator/linux-x86_64/emulator -system ./out/target/product/generic_x86_64/system-qemu.img -data ./out/target/product/generic_x86_64/data.img -ramdisk ./out/target/product/generic_x86_64/ramdisk-qemu.img -vendor ./out/target/product/generic_x86_64/vendor-qemu.img -gpu on -memory 4096 -verbose -show-kernel
1
$ ./prebuilts/android-emulator/linux-x86_64/emulator -system ./out/target/product/generic_x86_64/system-qemu.img -data ./out/target/product/generic_x86_64/data.img -ramdisk ./out/target/product/generic_x86_64/ramdisk-qemu.img -vendor ./out/target/product/generic_x86_64/vendor-qemu.img -gpu on -memory 4096 -verbose -show-kernel

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值