1 Star 0 Fork 0

HZH/frida-ios-dump

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
dump.js 11.45 KB
一键复制 编辑 原始数据 按行查看 历史
AloneMonkey 提交于 2019-07-24 10:59 . [bugfix] dlopen parameter problem.
Module.ensureInitialized('Foundation');
var O_RDONLY = 0;
var O_WRONLY = 1;
var O_RDWR = 2;
var O_CREAT = 512;
var SEEK_SET = 0;
var SEEK_CUR = 1;
var SEEK_END = 2;
function allocStr(str) {
return Memory.allocUtf8String(str);
}
function putStr(addr, str) {
if (typeof addr == "number") {
addr = ptr(addr);
}
return Memory.writeUtf8String(addr, str);
}
function getByteArr(addr, l) {
if (typeof addr == "number") {
addr = ptr(addr);
}
return Memory.readByteArray(addr, l);
}
function getU8(addr) {
if (typeof addr == "number") {
addr = ptr(addr);
}
return Memory.readU8(addr);
}
function putU8(addr, n) {
if (typeof addr == "number") {
addr = ptr(addr);
}
return Memory.writeU8(addr, n);
}
function getU16(addr) {
if (typeof addr == "number") {
addr = ptr(addr);
}
return Memory.readU16(addr);
}
function putU16(addr, n) {
if (typeof addr == "number") {
addr = ptr(addr);
}
return Memory.writeU16(addr, n);
}
function getU32(addr) {
if (typeof addr == "number") {
addr = ptr(addr);
}
return Memory.readU32(addr);
}
function putU32(addr, n) {
if (typeof addr == "number") {
addr = ptr(addr);
}
return Memory.writeU32(addr, n);
}
function getU64(addr) {
if (typeof addr == "number") {
addr = ptr(addr);
}
return Memory.readU64(addr);
}
function putU64(addr, n) {
if (typeof addr == "number") {
addr = ptr(addr);
}
return Memory.writeU64(addr, n);
}
function getPt(addr) {
if (typeof addr == "number") {
addr = ptr(addr);
}
return Memory.readPointer(addr);
}
function putPt(addr, n) {
if (typeof addr == "number") {
addr = ptr(addr);
}
if (typeof n == "number") {
n = ptr(n);
}
return Memory.writePointer(addr, n);
}
function malloc(size) {
return Memory.alloc(size);
}
function getExportFunction(type, name, ret, args) {
var nptr;
nptr = Module.findExportByName(null, name);
if (nptr === null) {
console.log("cannot find " + name);
return null;
} else {
if (type === "f") {
var funclet = new NativeFunction(nptr, ret, args);
if (typeof funclet === "undefined") {
console.log("parse error " + name);
return null;
}
return funclet;
} else if (type === "d") {
var datalet = Memory.readPointer(nptr);
if (typeof datalet === "undefined") {
console.log("parse error " + name);
return null;
}
return datalet;
}
}
}
var NSSearchPathForDirectoriesInDomains = getExportFunction("f", "NSSearchPathForDirectoriesInDomains", "pointer", ["int", "int", "int"]);
var wrapper_open = getExportFunction("f", "open", "int", ["pointer", "int", "int"]);
var read = getExportFunction("f", "read", "int", ["int", "pointer", "int"]);
var write = getExportFunction("f", "write", "int", ["int", "pointer", "int"]);
var lseek = getExportFunction("f", "lseek", "int64", ["int", "int64", "int"]);
var close = getExportFunction("f", "close", "int", ["int"]);
var remove = getExportFunction("f", "remove", "int", ["pointer"]);
var access = getExportFunction("f", "access", "int", ["pointer", "int"]);
var dlopen = getExportFunction("f", "dlopen", "pointer", ["pointer", "int"]);
function getDocumentDir() {
var NSDocumentDirectory = 9;
var NSUserDomainMask = 1;
var npdirs = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, 1);
return ObjC.Object(npdirs).objectAtIndex_(0).toString();
}
function open(pathname, flags, mode) {
if (typeof pathname == "string") {
pathname = allocStr(pathname);
}
return wrapper_open(pathname, flags, mode);
}
var modules = null;
function getAllAppModules() {
modules = new Array();
var tmpmods = Process.enumerateModulesSync();
for (var i = 0; i < tmpmods.length; i++) {
if (tmpmods[i].path.indexOf(".app") != -1) {
modules.push(tmpmods[i]);
}
}
return modules;
}
var FAT_MAGIC = 0xcafebabe;
var FAT_CIGAM = 0xbebafeca;
var MH_MAGIC = 0xfeedface;
var MH_CIGAM = 0xcefaedfe;
var MH_MAGIC_64 = 0xfeedfacf;
var MH_CIGAM_64 = 0xcffaedfe;
var LC_SEGMENT = 0x1;
var LC_SEGMENT_64 = 0x19;
var LC_ENCRYPTION_INFO = 0x21;
var LC_ENCRYPTION_INFO_64 = 0x2C;
function pad(str, n) {
return Array(n-str.length+1).join("0")+str;
}
function swap32(value) {
value = pad(value.toString(16),8)
var result = "";
for(var i = 0; i < value.length; i=i+2){
result += value.charAt(value.length - i - 2);
result += value.charAt(value.length - i - 1);
}
return parseInt(result,16)
}
function dumpModule(name) {
if (modules == null) {
modules = getAllAppModules();
}
var targetmod = null;
for (var i = 0; i < modules.length; i++) {
if (modules[i].path.indexOf(name) != -1) {
targetmod = modules[i];
break;
}
}
if (targetmod == null) {
console.log("Cannot find module");
return;
}
var modbase = modules[i].base;
var modsize = modules[i].size;
var newmodname = modules[i].name;
var newmodpath = getDocumentDir() + "/" + newmodname + ".fid";
var oldmodpath = modules[i].path;
if(!access(allocStr(newmodpath),0)){
remove(allocStr(newmodpath));
}
var fmodule = open(newmodpath, O_CREAT | O_RDWR, 0);
var foldmodule = open(oldmodpath, O_RDONLY, 0);
if (fmodule == -1 || foldmodule == -1) {
console.log("Cannot open file" + newmodpath);
return;
}
var is64bit = false;
var size_of_mach_header = 0;
var magic = getU32(modbase);
var cur_cpu_type = getU32(modbase.add(4));
var cur_cpu_subtype = getU32(modbase.add(8));
if (magic == MH_MAGIC || magic == MH_CIGAM) {
is64bit = false;
size_of_mach_header = 28;
}else if (magic == MH_MAGIC_64 || magic == MH_CIGAM_64) {
is64bit = true;
size_of_mach_header = 32;
}
var BUFSIZE = 4096;
var buffer = malloc(BUFSIZE);
read(foldmodule, buffer, BUFSIZE);
var fileoffset = 0;
var filesize = 0;
magic = getU32(buffer);
if(magic == FAT_CIGAM || magic == FAT_MAGIC){
var off = 4;
var archs = swap32(getU32(buffer.add(off)));
for (var i = 0; i < archs; i++) {
var cputype = swap32(getU32(buffer.add(off + 4)));
var cpusubtype = swap32(getU32(buffer.add(off + 8)));
if(cur_cpu_type == cputype && cur_cpu_subtype == cpusubtype){
fileoffset = swap32(getU32(buffer.add(off + 12)));
filesize = swap32(getU32(buffer.add(off + 16)));
break;
}
off += 20;
}
if(fileoffset == 0 || filesize == 0)
return;
lseek(fmodule, 0, SEEK_SET);
lseek(foldmodule, fileoffset, SEEK_SET);
for(var i = 0; i < parseInt(filesize / BUFSIZE); i++) {
read(foldmodule, buffer, BUFSIZE);
write(fmodule, buffer, BUFSIZE);
}
if(filesize % BUFSIZE){
read(foldmodule, buffer, filesize % BUFSIZE);
write(fmodule, buffer, filesize % BUFSIZE);
}
}else{
var readLen = 0;
lseek(foldmodule, 0, SEEK_SET);
lseek(fmodule, 0, SEEK_SET);
while(readLen = read(foldmodule, buffer, BUFSIZE)) {
write(fmodule, buffer, readLen);
}
}
var ncmds = getU32(modbase.add(16));
var off = size_of_mach_header;
var offset_cryptid = -1;
var crypt_off = 0;
var crypt_size = 0;
var segments = [];
for (var i = 0; i < ncmds; i++) {
var cmd = getU32(modbase.add(off));
var cmdsize = getU32(modbase.add(off + 4));
if (cmd == LC_ENCRYPTION_INFO || cmd == LC_ENCRYPTION_INFO_64) {
offset_cryptid = off + 16;
crypt_off = getU32(modbase.add(off + 8));
crypt_size = getU32(modbase.add(off + 12));
}
off += cmdsize;
}
if (offset_cryptid != -1) {
var tpbuf = malloc(8);
putU64(tpbuf, 0);
lseek(fmodule, offset_cryptid, SEEK_SET);
write(fmodule, tpbuf, 4);
lseek(fmodule, crypt_off, SEEK_SET);
write(fmodule, modbase.add(crypt_off), crypt_size);
}
close(fmodule);
close(foldmodule);
return newmodpath
}
function loadAllDynamicLibrary(app_path) {
var defaultManager = ObjC.classes.NSFileManager.defaultManager();
var errorPtr = Memory.alloc(Process.pointerSize);
Memory.writePointer(errorPtr, NULL);
var filenames = defaultManager.contentsOfDirectoryAtPath_error_(app_path, errorPtr);
for (var i = 0, l = filenames.count(); i < l; i++) {
var file_name = filenames.objectAtIndex_(i);
var file_path = app_path.stringByAppendingPathComponent_(file_name);
if (file_name.hasSuffix_(".framework")) {
var bundle = ObjC.classes.NSBundle.bundleWithPath_(file_path);
if (bundle.isLoaded()) {
console.log("[frida-ios-dump]: " + file_name + " has been loaded. ");
} else {
if (bundle.load()) {
console.log("[frida-ios-dump]: Load " + file_name + " success. ");
} else {
console.log("[frida-ios-dump]: Load " + file_name + " failed. ");
}
}
} else if (file_name.hasSuffix_(".bundle") ||
file_name.hasSuffix_(".momd") ||
file_name.hasSuffix_(".strings") ||
file_name.hasSuffix_(".appex") ||
file_name.hasSuffix_(".app") ||
file_name.hasSuffix_(".lproj") ||
file_name.hasSuffix_(".storyboardc")) {
continue;
} else {
var isDirPtr = Memory.alloc(Process.pointerSize);
Memory.writePointer(isDirPtr,NULL);
defaultManager.fileExistsAtPath_isDirectory_(file_path, isDirPtr);
if (Memory.readPointer(isDirPtr) == 1) {
loadAllDynamicLibrary(file_path);
} else {
if (file_name.hasSuffix_(".dylib")) {
var is_loaded = 0;
for (var j = 0; j < modules.length; j++) {
if (modules[j].path.indexOf(file_name) != -1) {
is_loaded = 1;
console.log("[frida-ios-dump]: " + file_name + " has been dlopen.");
break;
}
}
if (!is_loaded) {
if (dlopen(allocStr(file_path.UTF8String()), 9)) {
console.log("[frida-ios-dump]: dlopen " + file_name + " success. ");
} else {
console.log("[frida-ios-dump]: dlopen " + file_name + " failed. ");
}
}
}
}
}
}
}
function handleMessage(message) {
modules = getAllAppModules();
var app_path = ObjC.classes.NSBundle.mainBundle().bundlePath();
loadAllDynamicLibrary(app_path);
// start dump
modules = getAllAppModules();
for (var i = 0; i < modules.length; i++) {
console.log("start dump " + modules[i].path);
var result = dumpModule(modules[i].path);
send({ dump: result, path: modules[i].path});
}
send({app: app_path.toString()});
send({done: "ok"});
recv(handleMessage);
}
recv(handleMessage);
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/YellowZH_admin/frida-ios-dump.git
git@gitee.com:YellowZH_admin/frida-ios-dump.git
YellowZH_admin
frida-ios-dump
frida-ios-dump
master

搜索帮助