Redireccionamiento de funciones en bibliotecas nativas de Android

En este art铆culo, hablar茅 un poco sobre c贸mo puede redirigir las llamadas de funci贸n a bibliotecas nativas utilizando el marco de AndHook . Puede interceptar llamadas tanto p煤blicas (funciones exportadas) como no p煤blicas, directamente a su direcci贸n. Puede leer m谩s sobre la redirecci贸n aqu铆 y en la p谩gina del marco.


Como ejemplo, consideraremos el caso con la implementaci贸n de su biblioteca. Sin embargo, este marco tambi茅n le permite trabajar sin reconstruir la aplicaci贸n usando xposed.


En este art铆culo, usar茅 Visual Studio y BatchApkTool para Windows. En lugar de Visual Studio, puede usar Android Studio, o incluso compilarlo a trav茅s de gcc o clang (una opci贸n para avanzado). En lugar de BatchApkTool, puede usar apktool. No me detendr茅 en detalle sobre trabajar con BatchApkTool, porque Tratar con el trabajo en el programa no es dif铆cil.


Primero debes analizar el APK usando BatchApkTool o apktool.


Ahora descargue la biblioteca y el archivo de encabezado de la p谩gina del proyecto, para esto debe seguir este enlace y este enlace y descargar la biblioteca para su plataforma. (No encontr茅 la diferencia entre la versi贸n de Compat y la habitual, personalmente utilic茅 la versi贸n normal. Tal vez lo dir谩n en los comentarios)


Configurar Visual Studio para trabajar con NDK

Visual Studio Installer :



.


Crear un nuevo proyecto en Visual Studio

, , , .


" (Android)", .



:

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




, , , , .


. .



. .



, .cpp


#include "AndHook.h"

Creemos la funci贸n JNI_OnLoad, en la que registraremos nuestros ganchos.
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;
}

La funci贸n RegisterHooks en s铆 misma:


//       #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);
}

Tambi茅n para parchear bajo varias arquitecturas, es conveniente usar #define


Ejemplo
#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);

Una vez que hayamos terminado de escribir el c贸digo, debe compilarse.
Para hacer esto, necesitas:


Elija la plataforma de destino


Ensamblar proyecto


Si varias plataformas repiten los pasos 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