[Desarrollo inverso de Frida] Principio de bombardeo de Frida y el uso de herramientas de bombardeo


1. Suplemento de conocimientos

1. Proceso de operación de la aplicación después del refuerzo.

 1.    -->APP启动    
 2.        -->壳dex先加载起来    
 3.             -->壳负责把源dex文件读出来    
 4.                -->壳把源dex文件解密    
 5.                    -->把解密后的dex加载进内存 源dex运行起来
 

2. El principio del bombardeo

Una vez que se inicia la aplicación reforzada, el archivo dex de origen final se cargará en la memoria para su ejecución. En este momento, el archivo dex es el dex después de que se descifre el programa de endurecimiento, que es el código fuente de la aplicación.

El propósito de descomprimir Android es volcar el archivo dex de la aplicación descifrado de la memoria. Para lograr este propósito, necesitamos saber la dirección dex y el tamaño del archivo dex del archivo dex en la memoria. El archivo de biblioteca libart.so del sistema Android proporciona una función OpenMemory exportada para cargar el archivo dex.

Inserte la descripción de la imagen aquí
El primer parámetro de esta función apunta al archivo dex en la memoria.Si podemos conectar esta función, podemos obtener la dirección inicial del archivo dex cuando se carga en la memoria, y luego calcular el archivo dex guardado en el archivo. encabezado de acuerdo con el formato de archivo dex Length fileSize.

Comprenda el formato de archivo dex: https://www.jianshu.com/p/f7f0a712ddfe

posición inicial dex: el primer parámetro de OpenMemory

8个字节    magin  ---> dex 035
4个字节    校验位
20个字节   签名
-----32个字节开始------
4个字节    dex文件大小

Información disponible:

  • posición inicial dex (el primer parámetro de OpenMemory)
  • tamaño de archivo dex (posición inicial dex + 32 bytes)

Entonces podemos leer los datos en la memoria y escribirlos localmente

// 把内存里的数据读出来,从begin(dex在内存中的起始位置)开始读,取length长度(dex_size文件的大小)
file.write(Memory.readByteArray(begin, dex_size))
// 将这段读取出来的数据写入本地
var file = new File("/data/data/%s/" + dex_size + ".dex", "wb")

2. Demostración del proceso operativo

Antes de escribir el script de Frida, necesitamos encontrar el nombre de la función de exportación de OpenMemory en el archivo libart.so. Este nombre de función variará ligeramente dependiendo de la versión o arquitectura de Android.

¿Cuál es el nombre de esta función exportada?

Es equivalente a la interfaz proporcionada por el método en el archivo so al exterior OpenMemory. La forma de llamada del método en el archivo so en el código Java es:

javaCode.OpenMemory的导出函数名

OpenMemory导出函数名与so文件中的OpenMemory方法存在映射关系

java代码中想要调用so库中的OpenMemory方法就以它的导出函数名调用

Se pueden exportar diferentes librat.so según se utilice libart.so de 64 bits o de 32 bits durante la operación de la aplicación.

adb pull /system/lib/libart.so C:\Users\v_mcsong\Desktop
adb pull /system/lib64/libart.so C:\Users\v_mcsong\Desktop

Utilice IDA de 32/64 bits para abrir el archivo librat.so y ver OpenMemoryel nombre del método de exportación. Las diferentes versiones de Android pueden tener diferentes nombres de método de exportación.

Inserte la descripción de la imagen aquí
Es decir, la llamada _ZN3art7DexFile10OpenMemoryEPKhjRKNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEEjPNS_6MemMapEPKNS_10OatDexFileEPS9_está en la biblioteca soOpenMemory

Guión de bombardeo:

Proyecto de código abierto de referencia: https://github.com/dstmath/frida-unpack/blob/master/frida_unpack.py

#-*- coding:utf-8 -*-
# coding=utf-8
import frida
import sys

def on_message(message, data):
    base = message['payload']['base']
    size = int(message['payload']['size'])
    print(hex(base),size)
    # print session
    # dex_bytes = session.read_bytes(base, size)
    # f = open("1.dex","wb")
    # f.write(dex_bytes)
    # f.close()

### libart.so
# 9.0 arm 需要拦截 _ZN3art13DexFileLoader10OpenCommonEPKhjS2_jRKNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEEjPKNS_10OatDexFileEbbPS9_NS3_10unique_ptrINS_16DexFileContainerENS3_14default_deleteISH_EEEEPNS0_12VerifyResultE
# 7.0 arm:_ZN3art7DexFile10OpenMemoryEPKhjRKNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEEjPNS_6MemMapEPKNS_10OatDexFileEPS9_

# android 10: libdexfile.so 
# #_ZN3art13DexFileLoader10OpenCommonEPKhjS2_jRKNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEEjPKNS_10OatDexFileEbbPS9_NS3_10unique_ptrINS_16DexFileContainerENS3_14default_deleteISH_EEEEPNS0_12VerifyResultE

# 获取包名
package = sys.argv[1]
print("dex 导出目录为: /data/data/%s"%(package))
device = frida.get_usb_device()
pid = device.spawn(package)
session = device.attach(pid)
src = """
Interceptor.attach(Module.findExportByName("libart.so", "_ZN3art7DexFile10OpenMemoryEPKhjRKNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEEjPNS_6MemMapEPKNS_10OatDexFileEPS9_"), {
    onEnter: function (args) {
      	//dex文件的起始位置
        var begin = args[1]
        
        //dex文件的前8个字节是magic字段 看dex的文件格式说明
        //打印magic(会显示 "dex 035") 三个字符 可以验证是否为dex文件 
        console.log("magic : " + Memory.readUtf8String(begin))
     	
     	//把地址转换成整型 再加32 
        //因为dex文件的第32个字节处存放的是 dex文件的大小
        var address = parseInt(begin,16) + 0x20
        
		//把address地址指向的内存值读出来 该值就是dex的文件大小
        //ptr(address)转换的原因是 frida只接受 NativePointer类型指针
        var dex_size = Memory.readInt(ptr(address))
        console.log("dex_size :" + dex_size)
      
      	//frida写文件 把内存中的数据 写到本地
        var file = new File("/data/data/%s/" + dex_size + ".dex", "wb")

		//Memory.readByteArray(begin, length)
        //把内存里的数据读出来,从begin开始读,取length长度(dex_size文件的大小)
        file.write(Memory.readByteArray(begin, dex_size))
        file.flush()
        file.close()
        var send_data = {}
        send_data.base = parseInt(begin,16)
        send_data.size = dex_size
        send(send_data)
    },
    onLeave: function (retval) {
        if (retval.toInt32() > 0) {
        }
    }
});
"""%(package)

script = session.create_script(src)

script.on("message" , on_message)

script.load()
device.resume(pid)
sys.stdin.read()

Inserte la descripción de la imagen aquí
Inserte la descripción de la imagen aquí
Use jadx para abrir uno por uno y ver qué archivo dex es el código fuente de la aplicación.

Artículo de referencia: https://blog.51cto.com/yeshaochen/2496524

Supongo que te gusta

Origin blog.csdn.net/weixin_44032232/article/details/109676945
Recomendado
Clasificación