研究SandHook


SandHook的實現介紹:

Android ART Hook 實現 - SandHook_ganyao939543405的博客-CSDN博客_sandhook

SandHook/doc.md at master · asLody/SandHook

其中有一個重要的點就是,android內部實現java對象的時候會有一個mirror的鏡像對象,有一些虛擬機比較在意的類型,例如 Class,Method 這些 Art 內部所需要的類型,他們在 mirror 中是有對應的類型的。

ART在進行JIT/AOT的時候,會對dex代碼進行二次編譯的過程,也就是將原本的java class、method全都轉化成mirror:class、mirror:method。

AOSP源碼:https://android.googlesource.com/platform/art/+/8db4a405fe283d8769d5f38299d8692c009feb1a/runtime/mirror

這篇文章說的比較詳細:脫了馬甲我也認識你: 聊聊 Android 中類的真實形態 - 掘金

Sandhook 作者寫的文章:

SandHook 第三彈 - 性能優化 & Xposed 模塊 & 阻止 VM Inline_ganyao939543405的博客-CSDN博客

他遇到的一個問題就是VM Inline會將一定閾值內的代碼進行優化,這樣就會阻礙sandhook的hook過程,他的解決方法也是通過調整這個閾值來做處理。那我們來考慮,我們能不能實現改閾值將該優化的都優化了,導致他hook失敗呢。

跳轉圖:

非root注入:

https://github.com/ganyao114/SandBoxHookPlugin

沙箱環境的一種注入,是不是跟這個黑產工具類似呢。

整個的攻擊邏輯就是將apk下載到本地,黑產工具對他進行二次打包和插入dex指令集代碼(或者不用插入,直接sandhook修改就行。),但是apk中安裝到手機上的是存在sandhook的,不知道是為什么,可能跟下面這段代碼一樣吧,就是對某一個類進行hook操作(那么這個操作可能是對人臉識別的)。

SandHookConfig.libSandHookPath = soNewPath;
try {
    SandHook.addHookClass(ActivityHooker.class);
} catch (HookErrorException e) {
    e.printStackTrace();
}

我覺得最主要的就是對sandhook的檢測,他暴露很多特征,諸如修改那個閾值為0來做到組織inline的優化,還有類似的(如果可以的話,我們自己動手去修改這個值,再去檢測這個值,或者直接檢測這個值,如果這個值為0,那么就判斷為存在hook的情況[sandhook],sandhook中並沒有使用這個,其中關鍵特征_ZN3art3jit3Jit20jit_compiler_handle_E 並沒有使用,https://github.com/asLody/SandHook/blob/16a59fa0eef011ca202814311b362a8a3bcda412/hooklib/src/main/cpp/utils/hide_api.cpp#L93)。其次就是他的跳轉邏輯中會mmap一段可執行的區域,那么能不能通過之前寫的判斷smaps中的信息來做到檢測呢(這部分驗證需要自己寫一個sandhook的demo來做)。

其中對_ZN3art3jit3Jit20jit_compiler_handle_E做處理的是這些函數:

globalJitCompileHandlerAddr = reinterpret_cast<art::jit::JitCompiler **>(getSymCompat(art_lib_path, "_ZN3art3jit3Jit20jit_compiler_handle_E"));

art::jit::JitCompiler* getGlobalJitCompiler() {
    if (SDK_INT < ANDROID_N)
        return nullptr;
    if (globalJitCompileHandlerAddr == nullptr)
        return nullptr;
    return *globalJitCompileHandlerAddr;
}

art::CompilerOptions* getGlobalCompilerOptions() {
    return getCompilerOptions(getGlobalJitCompiler());
}

art::CompilerOptions* getCompilerOptions(art::jit::JitCompiler* compiler) {
    if (compiler == nullptr)
        return nullptr;
    return compiler->compilerOptions.get();
}

extern "C"
JNIEXPORT jboolean JNICALL
Java_com_swift_sandhook_SandHook_disableVMInline(JNIEnv *env, jclass type) {
    if (SDK_INT < ANDROID_N)
        return JNI_FALSE;
    replaceUpdateCompilerOptionsQ();
    art::CompilerOptions* compilerOptions = getGlobalCompilerOptions();
    if (compilerOptions == nullptr)
        return JNI_FALSE;
    return static_cast<jboolean>(disableJitInline(compilerOptions));
}

bool disableJitInline(art::CompilerOptions* compilerOptions) {
    if (compilerOptions == nullptr)
        return false;
    size_t originOptions = compilerOptions->getInlineMaxCodeUnits();
    //maybe a real inlineMaxCodeUnits
    if (originOptions > 0 && originOptions <= 1024) {
        compilerOptions->setInlineMaxCodeUnits(0);
        return true;
    } else {
        return false;
    }
}
// 通過dlsym進行拿到獲取。dlsym可能會被hook,還是需要自己實現一套。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM