內置Frida

將Frida內置進AOSP中

準備

  • 系統:Ubuntu20
  • aosp版本:10r2
  • 下載最新的ndk lts,我選擇22,我選擇最新的lts版本,在make的時候可能會要求讓你選擇22,所以選擇lts的上一個版本即可。
  • 確保GCC的版本在7.5以上
  • 相應的工具鏈要在PATH中,比如ptython3,Node.JS

編譯frida

下載相應的庫:

sudo apt-get install build-essential curl git lib32stdc++-9-dev ibc6-dev-i386 nodejs npm python3-dev python3-pip gcc-multilib g++-multilib

將NDK加入到環境變量中:

Export ANDROID_NDK_ROOT=your_ndk_path

Export PATH=\(ANDROID_NDK_ROOT:\)PATH

下載frida源碼:

git clone --recurse-submodules https://github.com/frida/frida.git

官方toolchainsdk下載地址如下

其中20210123fridareleng/deps.mk中的frida_deps_version

後面部分則是toolchain-{平臺+架構}.tar.bz2

https://build.frida.re/deps/20210123/toolchain-linux-x86_64.tar.bz2

https://build.frida.re/deps/20210123/sdk-linux-x86_64.tar.bz2

https://build.frida.re/deps/20210123/sdk-android-arm.tar.bz2

https://build.frida.re/deps/20210123/sdk-android-arm64.tar.bz2

可以手動下載上面的文件,然後在frida的文件夾下新建build文件夾

然後將文件放入build即可

現在執行releng/setup-env.sh

不過個人認爲手動方便一點,因爲編譯時的網絡訪問問題真的煩人(省略N字)

編譯frida:

make core-android-arm64

編譯成功:

img

編譯AOSP10

鏈接:https://pan.baidu.com/s/1MYTdT4pxMo8vsq5CxPFVZg

提取碼:yuov

下載aosp 10 源碼。

解壓後,下載驅動文件:https://developers.google.com/android/drivers#sailfishqp1a.190711.020

再執行驅動文件即可。

下載相應的庫:

sudo apt-get install -y openjdk-8-jdk

sudo apt-get install git-core gnupg flex bison gperf build-essential zip curl zlib1g-dev gcc-multilib g++-multilib libc6-dev-i386 lib32ncurses5-dev x11proto-core-dev libx11-dev lib32z-dev libgl1-mesa-dev libxml2-utils xsltproc unzip

編譯源碼

source build/envsetup.sh

lunch

選擇好對應的版本就進行編譯

M

如果出現如下錯誤:

[ 37% 50/135] test github.com/google/blueprint/pathtools

FAILED: out/soong/.bootstrap/blueprint-pathtools/test/test.passed

out/soong/.bootstrap/bin/gotestrunner -p ./build/blueprint/pathtools -f out/soong/.bootstrap/blueprint-pathtools/test/test.passed -- out/soong/.bootstrap/blueprint-pathtools/test/test -test.short

--- FAIL: TestGlobEscapes (0.00s)

--- FAIL: TestGlobEscapes//* (0.00s)

glob_test.go:562: incorrect matches list:

glob_test.go:562: pattern: "/"

glob_test.go:562: got: []string{"/", "a/", "b", "/a", "/b/", "/b/b", "a/a"}

glob_test.go:562: expected: []string{"", "/", "?", "a/", "b", "/", "/a", "/b/", "/b/b", "a/a"}

--- FAIL: TestGlobEscapes//* (0.00s)

glob_test.go:562: incorrect matches list:

glob_test.go:562: pattern: "/**"**

glob_test.go:562: got: []string(nil)

glob_test.go:562: expected: []string{"***", "***/"}

--- FAIL: TestGlobEscapes/**/* (0.00s)

glob_test.go:562: incorrect matches list:

glob_test.go:562: pattern: "**/"

glob_test.go:562: got: []string{"/a", "/b/"}

glob_test.go:562: expected: []string{"***/", "/a", "/b/"}*

--- FAIL: TestGlobEscapes/**//* (0.00s)

glob_test.go:562: incorrect matches list:

glob_test.go:562: pattern: "**//"

glob_test.go:562: got: []string{"/a", "/b/", "/b/b"}

glob_test.go:562: expected: []string{"***/", "/a", "/b/", "*/b/b"}

FAIL

05:04:52 soong bootstrap failed with: exit status 1

該錯誤應該是源碼問題,所以我後來使用repo重新同步了一次源碼

// 創建bin目錄
mkdir ~/bin
PATH=~/bin:$PATH
// 下載repo啓動器
curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo
chmod a+x ~/bin/repo
// 創建AOSP源碼目錄 
mkdir aosp10r2
cd aosp10r2
// 初始化源碼倉庫, 選擇與設備對應的源碼tag版本
repo init -u https://android.googlesource.com/platform/manifest -b android-10.0.0_r2
// 下載
repo sync

我這邊是掛梯子下載的,速度還行,如果不行請使用清華園或者是中科大。北清華、南科大。

編譯

M -j8

修改AOSP10r2源碼將frida內置

方案一,使用frida-gadget配合config文件來做配合。

根據gadget官網文檔中描述的,該方案已經被人利用成功過,所以直接站在巨人的肩膀上可以省力不少,其次,該方案不需要root權限,對於內置frida來說很方便,因爲root這個權限也是相當危險的。

方案二,userdebug模式,將frida內置到系統中

將編譯完成的frida-gadget.so拷貝出來,放到aosp10r2/out/target/product/sailfish/system/lib64/下

如果是32位的gadget,就放到aosp10r2/out/target/product/sailfish/system/lib/下,並都添加lib前綴。

其次還需要配置config文件,文件名爲libfrida-gadget.config.so,lib開頭,config.so結尾,中間的名字按照放到lib下的firda文件名來確定,內容如下:

{
  "interaction": {
    "type": "listen",
    "address": "127.0.0.1",
    "port": 27042,
    "on_load": "resume"
  }
}

64位frida-gadget.so在frida/build/frida-android-arm64/lib/frida/64/frida-gadget.so

修改aosp/framework/base/core/jni/com_android_internal_os_Zygote.cpp中的com_android_internal_os_Zygote_nativeForkAndSpecialize函數,以及需要在文件上面添加#include <dlfcn.h>,導入dlopen相關函數。

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) {
    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);
    }

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

    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);
      #if defined(__arm__) || defined(__arm64__)
        {
            #if defined(__arm__)
                #define FRIDA_LIB "/system/lib/libfrida-gadget_arm_32.so"
            #else
                #define FRIDA_LIB "/system/lib64/libfrida-gadget_arm_64.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;
}

刷機

Frida-ps -U沒問題,但是firda -UF 會有問題。

img

參考:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章