GKLBB

当你经历了暴风雨,你也就成为了暴风雨

导航

应用安全 --- frida脚本 之 so枚举

 

// 增强版:获取应用自身SO文件信息(带延迟和更智能的过滤)

// 使用setTimeout设置一个定时器,延迟5秒后执行内部的函数。
// 为什么需要延迟?因为App启动时,并不是所有的SO库都会立即加载。
// 很多库是在用户进行某些操作或App初始化到某个阶段后才动态加载的。
// 延迟执行可以大大增加捕获到所有关键SO库的可能性。
setTimeout(function() {
    // Java.perform是Frida的核心函数,它确保我们的代码在应用的Java虚拟机(JVM)上下文中执行。
    // 简单来说,所有需要与App的Java代码交互的操作(比如获取包名)都必须放在这里面。
    Java.perform(function() {
        // 在Frida控制台打印一条开始信息,方便调试和观察脚本执行状态。
        console.log("[*] 开始枚举应用自身的SO模块(增强版)...\n");
        
        // 调用Frida的Process.enumerateModules() API。
        // 这个API会返回一个数组,包含了当前目标进程加载到内存中的所有模块(.so, .jar, .dex, 可执行文件等)的详细信息。
        // 这是我们获取SO信息的基础数据源。
        var modules = Process.enumerateModules();
        
        // 初始化两个变量,用于存放后面获取到的应用包名和数据目录。
        // 初始值为null,表示我们还未获取到这些信息。
        var packageName = null;
        var dataDir = null;
        
        // 使用try...catch代码块来包裹获取应用信息的代码。
        // 为什么?因为在某些特殊情况或attach时机下,获取应用上下文可能会失败并抛出异常。
        // try...catch可以捕获这个异常,防止整个脚本因错误而崩溃,并能优雅地切换到备用方案。
        try {
            // --- 智能过滤的第一步:尝试获取精确的应用信息 ---
            
            // 加载Android系统中的'android.app.ActivityThread'这个类。
            // 这是一个非常核心的类,可以看作是应用主线程的管理者,通过它可以拿到应用的全局上下文。
            var ActivityThread = Java.use("android.app.ActivityThread");
            // 调用它的静态方法currentApplication()获取当前应用的Application实例。
            var app = ActivityThread.currentApplication();
            
            // 如果成功获取到了Application实例 (app不为null)
            if (app) {
                // 通过Application实例获取应用的上下文(Context)。Context是访问Android系统功能的“钥匙”。
                var context = app.getApplicationContext();
                // 从上下文中获取应用的包名,例如 "com.example.myapp"。
                packageName = context.getPackageName();
                // 从上下文中获取应用的数据目录,通常是 "/data/data/com.example.myapp"。
                dataDir = context.getApplicationInfo().dataDir;
                // 打印获取到的信息,让我们知道脚本工作正常。
                console.log("[*] 检测到应用包名: " + packageName);
                console.log("[*] 应用数据目录: " + dataDir + "\n");
            } else {
                // 如果第一种方法失败了 (比如在某些系统进程中),尝试第二种备用方案。
                // 这种方法不常用,且不一定成功,但作为备选可以增加脚本的健壮性。
                var activity = Java.use("android.app.Activity");
                var currentActivity = activity.$new(); // 尝试创建一个Activity实例
                if (currentActivity) {
                    var context = currentActivity.getApplicationContext();
                    packageName = context.getPackageName();
                    dataDir = context.getApplicationInfo().dataDir;
                    console.log("[*] 检测到应用包名: " + packageName);
                    console.log("[*] 应用数据目录: " + dataDir + "\n");
                } else {
                     // 如果所有方法都失败了,打印提示信息。
                    console.log("[!] 无法获取应用上下文,将使用路径启发式过滤方法\n");
                }
            }
        } catch (e) {
            // 如果try代码块中发生任何错误,就会执行这里的代码。
            console.log("[!] 无法自动检测应用信息: " + e.message);
            console.log("[!] 将使用路径启发式过滤方法\n");
        }
        
        // --- 核心过滤逻辑 ---
        // 使用JavaScript的filter方法遍历之前获取的所有模块(modules数组)。
        // filter会为每个模块执行一次内部的匿名函数,如果函数返回true,则保留该模块,否则丢弃。
        var appSoModules = modules.filter(function(module) {
            // **过滤条件1:必须是SO文件**
            // 检查模块的路径(path)或名称(name)是否以 ".so" 结尾。如果不是,直接返回false,排除掉。
            if (!module.path.endsWith('.so') && !module.name.endsWith('.so')) {
                return false;
            }
            
            // **过滤条件2:排除系统库**
            // 定义一个包含常见系统库路径前缀的数组。
            var systemPaths = [
                "/system/", "/vendor/", "/apex/", "/odm/",
                "/product/", "/system_ext/", "/bin/", "/sbin/",
                "/data/dalvik-cache/", "/data/misc/", "/data/local/"
            ];
            
            // 使用some方法检查模块的路径是否包含上面数组中的任何一个系统路径。
            // some() 会遍历systemPaths,只要有一个路径前缀在module.path中找到了,它就返回true。
            var isSystemLib = systemPaths.some(function(path) {
                return module.path.indexOf(path) !== -1;
            });
            
            // 如果isSystemLib为true,说明是系统库,返回false,排除掉。
            if (isSystemLib) return false;
            
            // **过滤条件3:智能判断是否为应用自身SO**
            // 如果我们之前成功获取了包名(packageName不为null)
            if (packageName) {
                // 那么,如果一个SO文件的路径包含了应用的包名(如 /data/app/~~com.example.myapp-xxxx/lib/arm64/libnative.so)
                // 或者包含了应用的数据目录(如 /data/data/com.example.myapp/lib/libnative.so)
                // 或者位于通用的应用安装目录 /data/app/ 下
                // 我们就极有理由相信它是应用自身的SO文件,返回true,保留它。
                return module.path.indexOf(packageName) !== -1 || 
                       module.path.indexOf(dataDir) !== -1 ||
                       module.path.indexOf("/data/app/") !== -1;
            }
            
            // **过滤条件4:启发式(Heuristic)过滤**
            // 如果没能获取到包名,我们就只能靠“猜”。
            // 通常,应用的SO文件会存在于/data/app/或/data/data/目录下。
            // 检查路径是否包含这些关键目录,作为判断依据。
            // `indexOf("/lib/")` 是一个比较宽泛的补充条件,可能会误伤,但能召回一些特殊情况。
            return module.path.indexOf("/data/app/") !== -1 ||
                   module.path.indexOf("/data/data/") !== -1;
        });
        
        // --- 兜底逻辑:防止过滤后列表为空 ---
        // 如果经过上面的严格过滤,一个SO文件都没找到(可能是某些特殊应用或过滤规则不适用)
        if (appSoModules.length === 0) {
            console.log("[!] 未找到应用SO文件,显示所有非系统SO文件:\n");
            // 我们就放宽条件,重新进行一次过滤。
            appSoModules = modules.filter(function(module) {
                // 条件1:必须是SO文件
                if (!module.path.endsWith('.so') && !module.name.endsWith('.so')) {
                    return false;
                }
                
                // 条件2:只排除系统库
                var systemPaths = [
                    "/system/", "/vendor/", "/apex/", "/odm/",
                    "/product/", "/system_ext/", "/bin/", "/sbin/",
                    "/data/dalvik-cache/", "/data/misc/", "/data/local/"
                ];
                
                // 这里用 "!" 取反,意思是:只要不是系统库,就返回true,保留下来。
                return !systemPaths.some(function(path) {
                    return module.path.indexOf(path) !== -1;
                });
            });
        }
        
        // --- 格式化输出结果 ---
        // 打印表头。padEnd()是字符串方法,用于在末尾填充空格,使字符串达到指定长度,从而实现列对齐。
        console.log("模块名称".padEnd(35) + 
                    "内存起始地址".padEnd(18) + 
                    "大小".padEnd(12) + 
                    "路径");
        // 打印一条分隔线,让表格更清晰。
        console.log("-".repeat(100));
        
        // 初始化一个变量用于计算所有找到的SO文件的总大小。
        var totalSize = 0;
        
        // 遍历最终筛选出的appSoModules数组。
        appSoModules.forEach(function(module) {
            // 从每个module对象中提取需要的信息。
            var baseAddress = module.base; // 模块在内存中的起始地址
            var size = module.size;       // 模块占用内存的大小(字节)
            var name = module.name;       // 模块的名称 (如 libnative-lib.so)
            var path = module.path;       // 模块在文件系统中的完整路径
            totalSize += size;            // 将当前模块的大小累加到总大小中。
            
            // 格式化并打印每一行数据,与表头对齐。
            // baseAddress.toString(16) 将地址转换为16进制字符串。
            console.log(name.padEnd(35) + 
                        "0x" + baseAddress.toString(16).padEnd(16) + 
                        (size + " B").padEnd(12) + 
                        path);
        });
        
        // 打印另一条分隔线。
        console.log("-".repeat(100));
        // 打印统计结果:总共多少个模块,总大小是多少(同时提供字节和KB两种单位)。
        console.log("总计: " + appSoModules.length + " 个模块, " + 
                    totalSize + " 字节 (" + Math.round(totalSize/1024) + " KB)");
        
        // --- 额外信息:按加载顺序显示 ---
        // 如果找到了至少一个SO模块
        if (appSoModules.length > 0) {
            console.log("\n[*] 按加载地址排序:");
            // 使用sort方法对模块数组进行排序。
            // 排序的规则是比较两个模块(a, b)的基地址(base)。
            // a.base.compare(b.base) 会根据地址大小返回-1, 0, 或 1,从而实现升序排列。
            // 排序后,列表的顺序就大致对应了SO库被加载到内存中的顺序。
            var sortedModules = appSoModules.sort(function(a, b) {
                return a.base.compare(b.base);
            });
            
            // 遍历排序后的数组,并打印出序号、名称和加载地址。
            sortedModules.forEach(function(module, index) {
                console.log("  " + (index+1) + ". " + module.name + " @ 0x" + 
                            module.base.toString(16));
            });
        }
    });
}, 5000); // 5000毫秒 = 5秒
 

执行后输出

C:\Users\21558\Downloads\frida_dump-master (2)\frida_dump-master>frida -U -l 2.js -f com.shizhuang.duapp
     ____
    / _  |   Frida 17.2.15 - A world-class dynamic instrumentation toolkit
   | (_| |
    > _  |   Commands:
   /_/ |_|       help      -> Displays the help system
   . . . .       object?   -> Display information about 'object'
   . . . .       exit/quit -> Exit
   . . . .
   . . . .   More info at https://frida.re/docs/home/
   . . . .
   . . . .   Connected to 2112123AC (id=adb-KCAIKN05L048ZAF-ovuptT._adb-tls-connect._tcp)
Spawned `com.shizhuang.duapp`. Resuming main thread!
[2112123AC::com.shizhuang.duapp ]-> [*] 开始枚举应用自身的SO模块(增强版)...

[*] 检测到应用包名: com.shizhuang.duapp
[*] 应用数据目录: Java.Field{holder: ApplicationInfo{a9ca16f com.shizhuang.duapp}, fieldType: 2, fieldReturnType: Ljava/lang/String;, value: /data/user/0/com.shizhuang.duapp}

模块名称                               内存起始地址            大小          路径
----------------------------------------------------------------------------------------------------
libGameVMP.so                      0x73b9b0a000      454656 B    /data/app/~~YxjKiMfU5GhbqDTDhPhhpw==/com.shizhuang.duapp-f6V4lziH2H4ySLWwb1S4_A==/lib/arm64/libGameVMP.so
libmmkv.so                         0x7347a1b000      532480 B    /data/app/~~YxjKiMfU5GhbqDTDhPhhpw==/com.shizhuang.duapp-f6V4lziH2H4ySLWwb1S4_A==/lib/arm64/libmmkv.so
libxdl.so                          0x734790d000      53248 B     /data/app/~~YxjKiMfU5GhbqDTDhPhhpw==/com.shizhuang.duapp-f6V4lziH2H4ySLWwb1S4_A==/lib/arm64/libxdl.so
libxcrash.so                       0x7347957000      118784 B    /data/app/~~YxjKiMfU5GhbqDTDhPhhpw==/com.shizhuang.duapp-f6V4lziH2H4ySLWwb1S4_A==/lib/arm64/libxcrash.so
libdulog.so                        0x733f092000      114688 B    /data/app/~~YxjKiMfU5GhbqDTDhPhhpw==/com.shizhuang.duapp-f6V4lziH2H4ySLWwb1S4_A==/lib/arm64/libdulog.so
libshadowhook.so                   0x733cc1e000      81920 B     /data/app/~~YxjKiMfU5GhbqDTDhPhhpw==/com.shizhuang.duapp-f6V4lziH2H4ySLWwb1S4_A==/lib/arm64/libshadowhook.so
liboaid_crash_fixer_so_loader.so   0x733ca23000      36864 B     /data/app/~~YxjKiMfU5GhbqDTDhPhhpw==/com.shizhuang.duapp-f6V4lziH2H4ySLWwb1S4_A==/lib/arm64/liboaid_crash_fixer_so_loader.so
libduhook.so                       0x733ca8f000      1220608 B   /data/app/~~YxjKiMfU5GhbqDTDhPhhpw==/com.shizhuang.duapp-f6V4lziH2H4ySLWwb1S4_A==/lib/arm64/libduhook.so
libc++_shared.so                   0x733cc5a000      929792 B    /data/app/~~YxjKiMfU5GhbqDTDhPhhpw==/com.shizhuang.duapp-f6V4lziH2H4ySLWwb1S4_A==/lib/arm64/libc++_shared.so
libxhook.so                        0x733cbdd000      53248 B     /data/app/~~YxjKiMfU5GhbqDTDhPhhpw==/com.shizhuang.duapp-f6V4lziH2H4ySLWwb1S4_A==/lib/arm64/libxhook.so
libxunwind.so                      0x733ca50000      69632 B     /data/app/~~YxjKiMfU5GhbqDTDhPhhpw==/com.shizhuang.duapp-f6V4lziH2H4ySLWwb1S4_A==/lib/arm64/libxunwind.so
libduHA.so                         0x733b8c6000      12288 B     /data/app/~~YxjKiMfU5GhbqDTDhPhhpw==/com.shizhuang.duapp-f6V4lziH2H4ySLWwb1S4_A==/lib/arm64/libduHA.so
libszstone.so                      0x733b68d000      2220032 B   /data/app/~~YxjKiMfU5GhbqDTDhPhhpw==/com.shizhuang.duapp-f6V4lziH2H4ySLWwb1S4_A==/lib/arm64/libszstone.so
libdewuhelper.so                   0x733a544000      28672 B     /data/app/~~YxjKiMfU5GhbqDTDhPhhpw==/com.shizhuang.duapp-f6V4lziH2H4ySLWwb1S4_A==/lib/arm64/libdewuhelper.so
libdusanwa.so                      0x733a50f000      139264 B    /data/app/~~YxjKiMfU5GhbqDTDhPhhpw==/com.shizhuang.duapp-f6V4lziH2H4ySLWwb1S4_A==/lib/arm64/libdusanwa.so
libkbArt.so                        0x733a4c0000      114688 B    /data/app/~~YxjKiMfU5GhbqDTDhPhhpw==/com.shizhuang.duapp-f6V4lziH2H4ySLWwb1S4_A==/lib/arm64/libkbArt.so
libdu_mediacache.so                0x733a216000      2744320 B   /data/app/~~YxjKiMfU5GhbqDTDhPhhpw==/com.shizhuang.duapp-f6V4lziH2H4ySLWwb1S4_A==/lib/arm64/libdu_mediacache.so
libmonochrome_64.so                0x73701e7000      183156736 B /data/app/~~LsoxdtSgGQhOGoQClL7nGQ==/com.google.android.trichromelibrary_636712333-F1txeyJUk4kuPZelwpCAuQ==/base.apk!/lib/arm64-v8a/libmonochrome_64.so
libnative-crypto-hook.so           0x7311723000      69632 B     /data/app/~~YxjKiMfU5GhbqDTDhPhhpw==/com.shizhuang.duapp-f6V4lziH2H4ySLWwb1S4_A==/lib/arm64/libnative-crypto-hook.so
libimagepipeline.so                0x7301213000      16384 B     /data/app/~~YxjKiMfU5GhbqDTDhPhhpw==/com.shizhuang.duapp-f6V4lziH2H4ySLWwb1S4_A==/lib/arm64/libimagepipeline.so
libfbjni.so                        0x73011c2000      200704 B    /data/app/~~YxjKiMfU5GhbqDTDhPhhpw==/com.shizhuang.duapp-f6V4lziH2H4ySLWwb1S4_A==/lib/arm64/libfbjni.so
libduv8.so                         0x72c12c1000      15179776 B  /data/app/~~YxjKiMfU5GhbqDTDhPhhpw==/com.shizhuang.duapp-f6V4lziH2H4ySLWwb1S4_A==/lib/arm64/libduv8.so
libyoga.so                         0x72dae0d000      184320 B    /data/app/~~YxjKiMfU5GhbqDTDhPhhpw==/com.shizhuang.duapp-f6V4lziH2H4ySLWwb1S4_A==/lib/arm64/libyoga.so
libhawk.so                         0x72b91c9000      1994752 B   /data/app/~~YxjKiMfU5GhbqDTDhPhhpw==/com.shizhuang.duapp-f6V4lziH2H4ySLWwb1S4_A==/lib/arm64/libhawk.so
libByteVC1_dec.so                  0x729020e000      450560 B    /data/app/~~YxjKiMfU5GhbqDTDhPhhpw==/com.shizhuang.duapp-f6V4lziH2H4ySLWwb1S4_A==/lib/arm64/libByteVC1_dec.so
libttheif_dec.so                   0x7299343000      147456 B    /data/app/~~YxjKiMfU5GhbqDTDhPhhpw==/com.shizhuang.duapp-f6V4lziH2H4ySLWwb1S4_A==/lib/arm64/libttheif_dec.so
libheif.so                         0x72a309f000      65536 B     /data/app/~~YxjKiMfU5GhbqDTDhPhhpw==/com.shizhuang.duapp-f6V4lziH2H4ySLWwb1S4_A==/lib/arm64/libheif.so
libstatic-webp.so                  0x7246f86000      569344 B    /data/app/~~YxjKiMfU5GhbqDTDhPhhpw==/com.shizhuang.duapp-f6V4lziH2H4ySLWwb1S4_A==/lib/arm64/libstatic-webp.so
libdu_heif.so                      0x7228981000      1806336 B   /data/data/com.shizhuang.duapp/files/soloader_x64/libdu_heif.so
libxyp2psdk.so                     0x722754a000      3100672 B   /data/data/com.shizhuang.duapp/files/soloader_x64/libxyp2psdk.so
libijmdetect_drisk.so              0x7221c63000      1417216 B   /data/data/com.shizhuang.duapp/files/soloader_x64/libijmdetect_drisk.so
libdu_security.so                  0x7221c12000      172032 B    /data/data/com.shizhuang.duapp/files/soloader_x64/libdu_security.so
----------------------------------------------------------------------------------------------------
总计: 32 个模块, 217456640 字节 (212360 KB)

[*] 按加载地址排序:
  1. libdu_security.so @ 0x7221c12000
  2. libijmdetect_drisk.so @ 0x7221c63000
  3. libxyp2psdk.so @ 0x722754a000
  4. libdu_heif.so @ 0x7228981000
  5. libstatic-webp.so @ 0x7246f86000
  6. libByteVC1_dec.so @ 0x729020e000
  7. libttheif_dec.so @ 0x7299343000
  8. libheif.so @ 0x72a309f000
  9. libhawk.so @ 0x72b91c9000
  10. libduv8.so @ 0x72c12c1000
  11. libyoga.so @ 0x72dae0d000
  12. libfbjni.so @ 0x73011c2000
  13. libimagepipeline.so @ 0x7301213000
  14. libnative-crypto-hook.so @ 0x7311723000
  15. libdu_mediacache.so @ 0x733a216000
  16. libkbArt.so @ 0x733a4c0000
  17. libdusanwa.so @ 0x733a50f000
  18. libdewuhelper.so @ 0x733a544000
  19. libszstone.so @ 0x733b68d000
  20. libduHA.so @ 0x733b8c6000
  21. liboaid_crash_fixer_so_loader.so @ 0x733ca23000
  22. libxunwind.so @ 0x733ca50000
  23. libduhook.so @ 0x733ca8f000
  24. libxhook.so @ 0x733cbdd000
  25. libshadowhook.so @ 0x733cc1e000
  26. libc++_shared.so @ 0x733cc5a000
  27. libdulog.so @ 0x733f092000
  28. libxdl.so @ 0x734790d000
  29. libxcrash.so @ 0x7347957000
  30. libmmkv.so @ 0x7347a1b000
  31. libmonochrome_64.so @ 0x73701e7000
  32. libGameVMP.so @ 0x73b9b0a000
[2112123AC::com.shizhuang.duapp ]->

为什么要延时加载,因为so先加载系统库,在记载应用so库,如果直接枚举只有系统so

 

posted on 2025-08-21 06:31  GKLBB  阅读(43)  评论(0)    收藏  举报