Android逆向系列--Dump So文件

本文介绍了如何在Android环境中使用Frida和C代码来Dump内存中的数据,特别是针对加密或动态下发的SO文件。通过提供的代码示例,展示了如何找到目标模块并将其保存到本地文件中,为逆向工程和安全分析提供了便利。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

背景

Android如何Dump内存中的数据,比如so文件

  • 有时候so文件是加密或者动态下发,需要从内存中Dump出来后进行使用
  • 可以直接使用下面的代码,编译生成bin

Show me the Code

Frida方案
rpc.exports = {
    findmodule: function(so_name) {
        var libso = Process.findModuleByName(so_name);
        return libso;
    },
    dumpmodule: function(so_name) {
        var libso = Process.findModuleByName(so_name);
        if (libso == null) {
            return -1;
        }
        Memory.protect(ptr(libso.base), libso.size, 'rwx');
        var libso_buffer = ptr(libso.base).readByteArray(libso.size);
        libso.buffer = libso_buffer;
        return libso_buffer;
    },
    allmodule: function() {
        return Process.enumerateModules()
    },
    arch: function() {
        return Process.arch;
    }
}
内存dump
function dump_memory(base,size) {
    Java.perform(function () {
        var currentApplication = Java.use("android.app.ActivityThread").currentApplication();
        var dir = currentApplication.getApplicationContext().getFilesDir().getPath();
        var file_path = dir + "/dumpmemory.bin";
        var file_handle = new File(file_path, "wb");
        if (file_handle && file_handle != null) {
            Memory.protect(ptr(base),size, 'rwx');
            var libso_buffer = ptr(base).readByteArray(size);
            file_handle.write(libso_buffer);
            file_handle.flush();
            file_handle.close();
            console.log("[dump]:", file_path);
        }
    });
}
dump_memory(0xbb25a208-2048,4096);
编译成C产物方案
#include <dlfcn.h>
#include <jni.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char** argv) {
  if (argc < 2) {
    printf("usage:./dump ./libxx.so /system/lib/libc.so ...");
    return 0;
  } else if (argc > 3) {
  }

  for (int i = 2; i < argc; i++) {
    printf("[+] dlopen %s\n", argv[i]);
    void* si = dlopen(argv[i], RTLD_LAZY);
    if (si == NULL) {
      printf("[-] dlopen depend so err!\n");
      return 0;
    }
  }

  JavaVM* vm;
  JNIEnv* env;
  jint res;

  JavaVMInitArgs vm_args;
  JavaVMOption options[1];
  options[0].optionString = "-Djava.class.path=.";
  vm_args.version = 0x00010002;
  vm_args.options = options;
  vm_args.nOptions = 1;
  vm_args.ignoreUnrecognized = JNI_TRUE;

  printf("[+] dlopen libdvm.so\n");
  void* handle =
      dlopen("/system/lib/libdvm.so", RTLD_LAZY);  // RTLD_LAZY RTLD_NOW
  if (!handle) {
    printf("[-] dlopen libdvm.so failed!!\n");
    return 0;
  }

  typedef int (*JNI_CreateJavaVM_Type)(JavaVM**, JNIEnv**, void*);
  JNI_CreateJavaVM_Type JNI_CreateJavaVM_Func =
      (JNI_CreateJavaVM_Type)dlsym(handle, "JNI_CreateJavaVM");
  if (!JNI_CreateJavaVM_Func) {
    printf("[-] dlsym failed\n");
    return 0;
  }
  res = JNI_CreateJavaVM_Func(&vm, &env, &vm_args);
  void* si = dlopen(argv[1], RTLD_LAZY);
  if (si == NULL) {
    printf("[-] dlopen err!\n");
    return 0;
  }

  void* addr = (void*)(*(int*)((size_t)si + 0x8c));
  uint32_t len = *(uint32_t*)((size_t)si + 0x90);
  char path[257] = "";
  sprintf(path, "%p_0x%x.so", addr, len);
  FILE* fp = fopen(path, "wb");
  printf("[+] save %s\n", path);
  fwrite(addr, 1, len, fp);
  fclose(fp);
  return 0;
}

参考

https://bbs.pediy.com/thread-259152.htm

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值