Redirecionamento de recurso em bibliotecas nativas do Android

Neste artigo, falarei um pouco sobre como vocĂȘ pode redirecionar chamadas de função para bibliotecas nativas usando a estrutura AndHook . VocĂȘ pode interceptar chamadas pĂșblicas (funçÔes exportadas) e nĂŁo pĂșblicas diretamente para o endereço delas. VocĂȘ pode ler mais sobre redirecionamento aqui e na pĂĄgina da estrutura.


Como exemplo, consideraremos o caso com a implementação de sua biblioteca. No entanto, essa estrutura tambĂ©m permite que vocĂȘ trabalhe sem reconstruir o aplicativo usando xposed.


Neste artigo, usarei o Visual Studio e o BatchApkTool para Windows. Em vez do Visual Studio, vocĂȘ pode usar o Android Studio ou atĂ© compilĂĄ-lo atravĂ©s do gcc ou clang (uma opção para avançado). Em vez do BatchApkTool, vocĂȘ pode usar o apktool. NĂŁo pararei em detalhes sobre o trabalho com o BatchApkTool, porque Lidar com o trabalho no programa nĂŁo Ă© difĂ­cil.


Primeiro, vocĂȘ precisa analisar o APK usando o BatchApkTool ou apktool.


Agora faça o download da biblioteca e do arquivo de cabeçalho na pågina do projeto. Para isso, siga este link e o link e faça o download da biblioteca para sua plataforma. (Eu não encontrei a diferença entre a versão do Compat e a usual, eu pessoalmente usei a versão normal. Talvez eles digam nos comentårios)


Configurando o Visual Studio para trabalhar com NDK

Visual Studio Installer :



.


Criando um novo projeto no Visual Studio

, , , .


" (Android)", .



:

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




, , , , .


. .



. .



, .cpp


#include "AndHook.h"

Vamos criar a função JNI_OnLoad, na qual registraremos nossos 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;
}

O RegisterHooks funciona em si:


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

Também para aplicar patches em vårias arquiteturas, é conveniente usar #define


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

Depois de terminar de escrever o cĂłdigo, ele deve ser compilado.
Para fazer isso, vocĂȘ precisa:


Escolha a plataforma de destino


Montar projeto


Se vĂĄrias plataformas repetirem as etapas 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