function get_self_process_name() {
var openPtr = Module.getExportByName('libc.so', 'open');
var open = new NativeFunction(openPtr, 'int', ['pointer', 'int']);
var readPtr = Module.getExportByName("libc.so", "read");
var read = new NativeFunction(readPtr, "int", ["int", "pointer", "int"]);
var closePtr = Module.getExportByName('libc.so', 'close');
var close = new NativeFunction(closePtr, 'int', ['int']);
var path = Memory.allocUtf8String("/proc/self/cmdline");
var fd = open(path, 0);
if (fd != -1) {
var buffer = Memory.alloc(0x1000);
var result = read(fd, buffer, 0x1000);
close(fd);
result = ptr(buffer).readCString();
return result
}
return "-1"
}
function Mkdir(path) {
if (path.indexOf("com") == -1) {
console.log("[Mkdir]-> Pass:", path);
return 0;
}
var mkdirPtr = Module.getExportByName('libc.so', 'mkdir');
var mkdir = new NativeFunction(mkdirPtr, 'int', ['pointer', 'int']);
var opendirPtr = Module.getExportByName('libc.so', 'opendir');
var opendir = new NativeFunction(opendirPtr, 'pointer', ['pointer']);
var closedirPtr = Module.getExportByName('libc.so', 'closedir');
var closedir = new NativeFunction(closedirPtr, 'int', ['pointer']);
var cPath = Memory.allocUtf8String(path);
var dir = opendir(cPath);
if (dir != 0) {
closedir(dir);
return 0
}
mkdir(cPath, 0o755);
chmod(path)
console.log("[Mkdir]->", path);
}
function chmod(path) {
var chmodPtr = Module.getExportByName('libc.so', 'chmod');
var chmod = new NativeFunction(chmodPtr, 'int', ['pointer', 'int']);
var cPath = Memory.allocUtf8String(path);
chmod(cPath, 755)
}
function dump_dex() {
var libart = Process.findModuleByName("libart.so");
var addr_DefineClass = null;
var symbols = libart.enumerateSymbols();
for (var index = 0; index < symbols.length; index++) {
var symbol = symbols[index];
var symbol_name = symbol.name;
if (symbol_name.indexOf("ClassLinker") >= 0 && symbol_name.indexOf("DefineClass") >= 0 && symbol_name.indexOf("Thread") >= 0 && symbol_name.indexOf("DexFile") >= 0) {
console.log(symbol_name, symbol.address);
addr_DefineClass = symbol.address
}
}
var dex_maps = {}
;
var dex_count = 1;
console.log("[DefineClass:]", addr_DefineClass);
if (addr_DefineClass) {
Interceptor.attach(addr_DefineClass, {
onEnter: function (args) {
var dex_file = args[5]; var base = ptr(dex_file).add(Process.pointerSize).readPointer(); var size = ptr(dex_file).add(Process.pointerSize + Process.pointerSize).readUInt(); if (dex_maps[base] == undefined) {
dex_maps[base] = size; var magic = ptr(base).readCString(); if (magic.indexOf("dex") == 0) {
var process_name = get_self_process_name(); if (process_name != "-1") {
var dex_dir_path = "/data/data/" + process_name + "/files"
Mkdir(dex_dir_path)
dex_dir_path += "/dump_dex"
Mkdir(dex_dir_path)
var dex_path = dex_dir_path + "/classes" + (dex_count == 1 ? "" : dex_count) + ".dex"; console.log("[find dex]:", dex_path); var fd = new File(dex_path, "wb");
if (fd && fd != null) {
dex_count++; var dex_buffer = ptr(base).readByteArray(size);
fd.write(dex_buffer); fd.flush();
fd.close(); console.log("[dump dex]:", dex_path)
}
}
}
}
}
, onLeave: function (retval) { }
})
}
}
var is_hook_libart = false;
function hook_dlopen() {
Interceptor.attach(Module.findExportByName(null, "dlopen"), {
onEnter: function (args) {
var pathptr = args[0]; if (pathptr !== undefined && pathptr != null) {
var path = ptr(pathptr).readCString(); if (path.indexOf("libart.so") >= 0) {
this.can_hook_libart = true; console.log("[dlopen:]", path)
}
}
}
, onLeave: function (retval) {
if (this.can_hook_libart && !is_hook_libart) {
dump_dex(); is_hook_libart = true
}
}
});
Interceptor.attach(Module.findExportByName(null, "android_dlopen_ext"), {
onEnter: function (args) {
var pathptr = args[0]; if (pathptr !== undefined && pathptr != null) {
var path = ptr(pathptr).readCString(); if (path.indexOf("libart.so") >= 0) {
this.can_hook_libart = true; console.log("[android_dlopen_ext:]", path)
}
}
}
, onLeave: function (retval) {
if (this.can_hook_libart && !is_hook_libart) {
dump_dex(); is_hook_libart = true
}
}
})
}
setImmediate(dump_dex);