Fitur pengalihan di perpustakaan asli Android

Di artikel ini, saya akan berbicara sedikit tentang bagaimana, menggunakan kerangka kerja AndHook , Anda dapat mengalihkan panggilan fungsi di pustaka asli. Anda dapat memotong panggilan baik publik (fungsi yang diekspor) dan non-publik, langsung ke alamat mereka. Anda dapat membaca lebih lanjut tentang pengalihan di sini dan di halaman kerangka kerja.


Sebagai contoh, kami akan mempertimbangkan kasus dengan implementasi perpustakaannya. Namun, kerangka kerja ini juga memungkinkan Anda untuk bekerja tanpa membangun kembali aplikasi menggunakan xposed.


Pada artikel ini, saya akan menggunakan Visual Studio dan BatchApkTool untuk Windows. Alih-alih Visual Studio, Anda dapat menggunakan Android Studio, atau bahkan mengompilasinya melalui gcc atau dentang (opsi untuk tingkat lanjut). Alih-alih BatchApkTool, Anda dapat menggunakan apktool. Saya tidak akan berhenti secara detail tentang bekerja dengan BatchApkTool, karena Berurusan dengan bekerja dalam program ini tidak sulit.


Pertama, Anda perlu mem-parsing APK menggunakan BatchApkTool atau apktool.


Sekarang unduh perpustakaan dan file header dari halaman proyek, untuk ini Anda harus mengikuti tautan ini dan tautan ini dan mengunduh perpustakaan untuk platform Anda. (Saya tidak menemukan perbedaan antara versi Compat dan versi yang biasa, saya pribadi menggunakan versi normal. Mungkin mereka akan memberi tahu di komentar)


Menyiapkan Visual Studio untuk bekerja dengan NDK

Visual Studio Installer :



.


Membuat proyek baru di Visual Studio

, , , .


" (Android)", .



:

. : , : < >, API 14 ARM X86, ARM64 X64 21 .
.
-> , :




, , , , .


. .



. .



, .cpp


#include "AndHook.h"

Mari kita buat fungsi JNI_OnLoad, di mana kita akan mendaftarkan kait kita.
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved)
{
    JNIEnv* env = NULL;
    jint result = -1;
    LOGD("JNI_OnLoad start!");

    if (vm->GetEnv((void**)&env, JNI_VERSION_1_4) != JNI_OK) {
        LOGE("JNI_OnLoad! GetEnv failed");
        return -1;
    }

    RegisterHooks();

    result = JNI_VERSION_1_4;
    LOGD("JNI_OnLoad! finished!");
    return result;
}

Fungsi RegisterHooks itu sendiri:


//       #define
#ifdef __arm__
#define Test_Offset 0x1234
#elif __aarch64__
#define Test_Offset 0x1235
#elif __i386__
#define Test_Offset 0x1236
#elif __x86_64__
#define Test_Offset 0x1237
#endif
void (*Old_Test)();
void Test()
{
    LOGD("Test!");
    // Do something
    Old_Test();
}
void (*Old_Test2)();
void Test2()
{
    LOGD("Test2!");
    Old_Test2(); //      Test2
}
void RegisterHooks() {
    const void* libil2cpp = AKGetImageByName("libil2cpp.so"); //     .
    if (libil2cpp == NULL) {
        LOGW("AKGetImageByName return null!");
        return;
    }

    //      
    //  -     IDA/Ghidra
    //    il2cpp-     https://github.com/Perfare/Il2CppDumper
    AKHookFunction(AKFindAnonymity(libil2cpp, Test_Offset), reinterpret_cast<void*>(&Test), reinterpret_cast<void**>(&Old_Test));
    //       Test_Offset   libil2cpp       Test,  .       Old_Test.

    //   
    AKHookFunction(AKFindSymbol(libil2cpp, "Test2"), reinterpret_cast<void*>(&Test2), reinterpret_cast<void**>(&Old_Test2));

    //         :
    void (*Test3)();
    Test3 = reinterpret_cast<void (*)()>(AKFindAnonymity(libil2cpp, 0x12345));
    Test3();

    //      
    const uint8_t data[] = { 0x00, 0xF0, 0x20, 0xE3 }; //  NOP
    AKPatchMemory(reinterpret_cast<const void*>(AKFindAnonymity(libil2cpp, 0x123456)), reinterpret_cast<const void*>(&data), 4);
    //       0x123456

    AKCloseImage(libil2cpp);
}

Juga untuk menambal di bawah beberapa arsitektur, mudah untuk menggunakan #define


Contoh
#ifdef __arm__
#define Patch_Offset 0x1234
#define Patch_Data { 0x00, 0xF0, 0x20, 0xE3 }
#elif __aarch64__
#define Patch_Offset 0x1234
#define Patch_Data { 0x1F, 0x20, 0x03, 0xD5 }
#endif

const uint8_t data[] = Patch_Data;
const size_t len = sizeof(data) / sizeof(uint8_t);
AKPatchMemory(reinterpret_cast<const void*>(AKFindAnonymity(libil2cpp, Patch_Offset)), reinterpret_cast<const void*>(&data), len);

Setelah kami selesai menulis kode, itu harus dikompilasi.
Untuk melakukan ini, Anda perlu:


Pilih platform target


Merakit proyek


Jika beberapa platform ulangi langkah 1-2.


AndHook lib . ( ).


. MainActivity . onCreate MainActivity :


const-string v0, "SharedObject1"
invoke-static {v0}, Ljava/lang/System;->loadLibrary(Ljava/lang/String;)V

SharedObject1 lib .so
il2cpp- MainActivity onCreate smali/com/unity3d/player/UnityPlayerActivity.smali.


.


:
https://github.com/asLody/AndHook/
http://armconverter.com/
http://armconverter.com/hextoarm/


All Articles