Frida加载APK/DEX/SO/dylib/文件并调用方法

Android

加载APK并调用方法

1. AndroidStudio创建项目

创建returnNum方法

2. build项目,将apk push手机中

1
adb push 1.apk /data/local/tmp

3. Frida加载APK调用方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
var DEXFactory = null
function loadAPK(path){
var ActivityThread = Java.use("android.app.ActivityThread");
var app = ActivityThread.currentApplication();
Java.classFactory.cacheDir = "/data/data/" + app.getPackageName() + "/cache";
Java.classFactory.codeCacheDir = "/data/data/" + app.getPackageName() + "/code_cache";
var DexClassLoader = Java.use("dalvik.system.DexClassLoader");
var DEXCL = DexClassLoader.$new(path, Java.classFactory.codeCacheDir, null, DexClassLoader.getSystemClassLoader());
DEXFactory = Java.ClassFactory.get(DEXCL);
DEXFactory.cacheDir = "/data/data/" + app.getPackageName() + "/cache";
DEXFactory.codeCacheDir = "/data/data/" + app.getPackageName() + "/code_cache";
}


Java.performNow(function(){
loadAPK("/data/local/tmp/1.apk");
var utils = DEXFactory.use("custom.dex.utils");
console.log(utils.returnNum());

});

加载APK并调用方法,此处方法只是简单的return 数字,也可以将一些复杂的逻辑放在APK中用于调用

加载DEX并调用方法

1
2
3
Java.openClassFile("/data/local/tmp/xxx.dex").load();
var utils = Java.use("custom.dex.utils");
console.log(utils.returnNum());

加载SO并调用方法

1
2
3
4
var moduleLibext = Module.load("/data/local/tmp/libxxxx.so");
var addrSayHello = moduleLibext.findExportByName("sayHello");
var funcSayHello = new NativeFunction(addrSayHello, "void", ["void"]);
funcSayHello();

iOS

  1. 生成.dylib文件

    注意:不要创建+ (void)load{}方法,加载动态库后APP会闪退

  1. 加载脚本

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    var  moduleLibext = null;
    function loadDylib(moduleName) {
    // var dlopen = new NativeFunction(Module.findExportByName(null, 'dlopen'), 'pointer', ['pointer', 'int']);
    // var path = Memory.allocUtf8String("/private/var/tmp/22.dylib");
    // var res = dlopen(path, 10);
    if (moduleLibext !==null){
    console.error("[*] 🍺🍺 Dylib already loaded 🍺🍺");
    return;
    }
    moduleLibext = Module.load(moduleName);
    console.error("[*] 🍺🍺 Dylib load sucess 🍺🍺");
    var enumerateImports = moduleLibext.enumerateExports();
    for (var i=0;i<enumerateImports.length;i++){
    console.error(`[*] name:${enumerateImports[i].name} type:${enumerateImports[i].type}`)
    }

    }


    function getModuleList(){
    Process.enumerateModules({
    onMatch: function(module){
    console.log('Module name: ' + module.name);
    console.log('Base address: ' + module.base);
    console.log('Size: ' + module.size);
    console.log('Path: ' + module.path);
    console.log('--------------------------------------------------------');
    },

    onComplete: function(){
    }

    });
    }


    function getExports(moduleName) {
    if (moduleLibext == null){
    loadDylib(moduleName)
    }
    var enumerateImports = moduleLibext.enumerateExports();
    for (var i=0;i<enumerateImports.length;i++){
    console.error(`\n[*] name:${enumerateImports[i].name} type:${enumerateImports[i].type}`)
    }

    }

    function getFuncPointer(moduleName,funcName,retunType,argTypes) {
    loadDylib(moduleName);
    var funcPointer = moduleLibext.findExportByName(funcName);
    return new NativeFunction(funcPointer, retunType,argTypes);
    }

    function exec(){

    var funcPointer = getFuncPointer("/private/var/tmp/libtools.dylib","custom","pointer",["pointer"]);
    var newStrObject = ObjC.classes.NSString.stringWithString_("hello~~~~");
    var pointerRet = funcPointer(newStrObject);
    var objectRet = new ObjC.Object(pointerRet);
    console.log(objectRet);
    }