es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Cargue las bibliotecas nativas de Android (JNI) en un programa nativo de c.

Voy a escribir un programa en c que carga una librería nativa de Android (.so) este es mi código:

#include <stdio.h>
#include <dlfcn.h>
#include <stdlib.h>

typedef void (*target_func)(JNIEnv* env, jobject obj, int x);

int main(int argc, char ** argv) {
    char *lib = "/path/to/lib.so";


    void *handle = dlopen(lib, RTLD_LAZY);

    if (NULL == handle) {
        printf("error al cargar la librería\n");
        return 1;
    }

    void *offset_func = dlsym(handle, "Java_com_example_test_MainActivity_myFunc");

    if (NULL == offset_func) {
        printf("error getprocaddress\n");
        return 1;
    }

    target_func target = (target_func)((unsigned char *)offset_func);


    target(nullptr, nullptr, 10);  // Aquí necesito pasar el puntero JNIEnv

    return 0;
}

Lo único que necesito es pasar el puntero JNIEnv (el primer parámetro), ¿hay alguna forma? Mi programa se ejecuta en un emulador de Android y por eso intenté resolver JNIEnv desde libart.so, pero no tuve éxito al desensamblar libart.so en IDA Pro.

Sé que cuando lanzamos un archivo apk en nuestro dispositivo, el ART (o Dalvik) crea JNIEnv para la aplicación, pero no sé cómo puedo emular y crear JNIEnv similar a ART.</stdlib.h></dlfcn.h></stdio.h>

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Como experto en TI especializado en Android, C, Android NDK, ingeniería inversa y biblioteca nativa de Android, puedo responder la siguiente pregunta:

    El puntero JNIEnv es un parámetro crucial para invocar métodos nativos desde Java en JNI (Java Native Interface). Contiene una tabla de punteros a funciones que permiten la comunicación entre Java y código nativo. Sin embargo, no es trivial crear un puntero JNIEnv válido en un programa C autónomo que cargue una biblioteca nativa de Android (.so).

    Un enfoque posible es realizar ingeniería inversa del enlazador/cargador dinámico (por ejemplo, linker.cpp) en el Proyecto de Código Abierto de Android (AOSP) para comprender cómo crea el puntero JNIEnv para cada proceso de aplicación. Esta puede ser una tarea desafiante, considerando la complejidad del tiempo de ejecución de Android y las características de seguridad que impiden la ejecución de código no autorizado.

    Otro enfoque es utilizar una herramienta como Frida, que permite inyectar una biblioteca dinámica en un proceso en ejecución para modificar su comportamiento o interceptar sus llamadas a funciones. Frida proporciona una API de JavaScript que puede interactuar con el puntero JNIEnv desde un script. Sin embargo, este enfoque requiere acceso root en el dispositivo/emulador y puede no ser factible en todos los escenarios.

    En resumen, si bien es técnicamente posible crear un puntero JNIEnv en un programa C autónomo, implica un esfuerzo significativo de ingeniería inversa y puede resultar en características no documentadas y no compatibles. Es posible que sea mejor explorar enfoques alternativos que aprovechen los marcos y herramientas existentes diseñados para interactuar con aplicaciones de Android desde código nativo.

Comments are closed.