Skip to content

vmtrace的发布仓库,相关so 调用脚本例子都会放在里面

Notifications You must be signed in to change notification settings

jiqiu2022/vm-trace-release

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

如何开始我们的trace之旅

demo测试包已经发布,在demo文件夹下 有配套的js和apk包

tracehelp.zip是辅助的面具模块,一定要刷入

test.so是trace的本体

注意事项

本trace目前仅支持了arm64架构,在一些老的机型上走的是arm32,是无法trace的,后面会优先支持

如果本仓库🌟破了800,将会开启ios版本的trace开发,不会食言

从零开始使用这个trace

前戏准备

这一步顾名思义就是准备环境

首先你要有一台系统在安卓14以下的设备,群友实测安卓14不可以

第二步刷入面具模块(支持Magisk,Kernelsu、Aptach)等各种,可以解包看一下原理,没干啥东西

第三步关闭 selinux

adb shell
su
setenfoce 0

第四步推送test.so到/data/local/tmp

开始trace

trace脚本有两种注入方法 attach/spwan

attach注入法

首先以文章中的xiaoyuan来做讲解

xiaoyuan带着msao,我们可以使用spwan使用过掉msao的脚本

然后在attach注入

frida -U -f com.fenbi.android.leo -l /Users/mac/Documents/androidtools/bypassmsao.js

CleanShot_2025_02_10_at_21_36_32

在这个状态下粘贴demo/xiaoyuan/xiaoyuan.js进到shell里

CleanShot_2025_02_10_at_21_37_18

然后按回车就可以了

如果遇到了这个报错

CleanShot_2025_02_10_at_21_38_09

首先你需要检查是否setenfore 0这个命令是否运行,因为selinux不关闭无法注入/data/local/tmp目录下的东西

第二要检查你是否把so移动到合适的位置

至于为什么是data/local/tmp 因为所有app都对这个目录有可读权限

var  dlopenPtr = Module.findExportByName(null, 'dlopen');
var  dlopen = new NativeFunction(dlopenPtr, 'pointer', ['pointer', 'int']);
var  soPath = "/data/local/tmp/test.so"; // 示例路径
var  soPathPtr = Memory.allocUtf8String(soPath);
var  handle = dlopen(soPathPtr, 2);

你可以在这里找到注入逻辑手动注入so到app进程中

CleanShot_2025_02_10_at_21_40_49

如果正常注入的话,你可以通过输入handle拿到注入so的数值

在一切注入无误后 我们可以主动调用

CleanShot_2025_02_10_at_21_41_38

在出现结果以后建议立马按ctrl+D 退出

CleanShot_2025_02_10_at_21_42_12

为什么要退出? 因为其他接口也会调用到这个函数逻辑里,如果不退出可能会出现log.log的内容和你frida打印不一致的情况

就没有什么别的好方法了吗? 有,让我们来看spwan注入方法

spwan注入方法 感谢D_Z66666大佬帮忙共同完成

这个脚本是trace某宝的

function prepareArgs(args) {
    if (args === undefined || !Array.isArray(args)) {
        args = [];
    }
    var argNum = args.length;
    var argSize = Process.pointerSize * argNum;
    var argsPtr = Memory.alloc(argSize);

    for (var i = 0; i < argNum; i++) {
        var arg = args[i];
        var argPtr;
        if (!arg) {
            arg = 0
        }
        if (arg instanceof NativePointer) {
            // 如果是 NativePointer,直接使用
            argPtr = arg;
        } else if (typeof arg === 'number') {
            // 如果是数字,直接转换为指针
            argPtr = ptr(arg);
        } else if (typeof arg === 'string') {
            // 如果是字符串,分配内存并获取指针
            argPtr = Memory.allocUtf8String(arg);
        } else if (typeof arg === 'object' && arg.hasOwnProperty('handle')) {
            // 如果是带有 handle 属性的对象(如 JNIEnv)
            argPtr = arg.handle;
        } else if (typeof arg === 'object' && arg instanceof ArrayBuffer) {
            // 如果是二进制数据,分配内存并写入数据
            var dataPtr = Memory.alloc(arg.byteLength);
            Memory.writeByteArray(dataPtr, arg);
            argPtr = dataPtr;
        } else {
            console.error('Unsupported argument type at index ' + i + ':', typeof arg);
            throw new TypeError('Unsupported argument type at index ' + i + ': ' + typeof arg);
        }

        // 将参数指针写入参数数组
        Memory.writePointer(argsPtr.add(i * Process.pointerSize), argPtr);
    }

    return {
        argsPtr: argsPtr,
        argNum: argNum
    };
}

var vmtraceAddr;
var vmtrace;


function hook_sub_1329B0() {
    var aimbase =Module.findBaseAddress("libsgmainso-6.6.231204.so");
    console.log("start hook");
    var targetFuncAddr = aimbase.add(0x1329B0);
    Interceptor.replace(targetFuncAddr, new NativeCallback(function (arg0,arg1,arg2,arg3,arg4,arg5) {
        console.log("trace调用了");
        Interceptor.revert(targetFuncAddr);
        Interceptor.flush();
        var args =[arg0,arg1,arg2,arg3,arg4,arg5];
        var {argsPtr, argNum} = prepareArgs(args);
        var argPtr1 = Memory.allocUtf8String("/data/user/0/com.taobao.taobao/log.txt");
        var res =vmtrace(targetFuncAddr, argsPtr,argNum,argPtr1,0);
        console.log(res)
        return res;
    }, 'pointer', ['pointer','pointer','pointer','pointer','pointer','pointer']));
}

function hook_soload() {
    var  dlopenPtr = Module.findExportByName(null, 'dlopen');
    var  dlopen = new NativeFunction(dlopenPtr, 'pointer', ['pointer', 'int']);
    var soPath = "/data/local/tmp/test.so"; // 示例路径
    var  soPathPtr = Memory.allocUtf8String(soPath);
    var handle = dlopen(soPathPtr, 2);
    console.log(handle);
    vmtraceAddr = Module.findExportByName("test.so", 'start_trace');
    vmtrace = new NativeFunction(vmtraceAddr, 'pointer', ['pointer', 'pointer', 'uint32', 'pointer', 'uint32']);

    var isinit = 0;
    var dlopen_addr = Module.findExportByName(null, "android_dlopen_ext");
    var find = 0;
    console.log("android_dlopen_ext: ", dlopen_addr);
    Interceptor.attach(dlopen_addr, {
        onEnter: function (args) {
            var addr = args[0];
            var str = ptr(addr).readCString();
            this.name = str;

            if (str.indexOf("libsgmainso-6.6.231204.so") >= 0) {
                console.log("dlopen==> " + (str));
                find = 1;
            } else {
                find = 0;
            }
        },
        onLeave: function (retval) {
            if (find > 0) {
                if (isinit == 0) {
                    hook_sub_1329B0();
                    isinit = 1;
                }

            }
        }
    })


}
setImmediate(hook_soload)

我来带大家简单读一下这个脚本,

hook了so加载的地方,当目标so加载完成的时候开始hook,但是如果你想hook init函数段则需要更改时机

Interceptor.revert(targetFuncAddr);
Interceptor.flush();

这两句代码保证被替换的函数只被替换一次后就被还原,保证你的trace只走一次,只生成一份log

防止一个高频调用的函数一直处于trace状态,导致trace文件被覆盖

注意 new NativeCallback(function (arg0,arg1,arg2,arg3,arg4,arg5)

参数的个数需要根据函数的签名填写,如果填写多了/少了就可能造成崩溃,所以最重要的是确定好要传入的参数

常见问题

我是否可以使用其他方法注入?

答:可以 xposed 还有zygisk等支持

也可以使用我的项目:

https://github.com/jiqiu2022/Zygisk-MyInjector/blob/main/module/src/main/cpp/hack.cpp

我在早期都是使用这个项目注入的

但是需要注释掉

CleanShot_2025_02_10_at_21_51_32

因为隐藏了以后就找不到了\

如果你使用非frida注入,可以无视掉每次开机的关闭selinux流程

Error: expected a pointer

CleanShot_2025_02_10_at_21_38_09

首先你需要检查是否setenfore 0这个命令是否运行,因为selinux不关闭无法注入/data/local/tmp目录下的东西

第二要检查你是否把so移动到合适的位置

至于为什么是data/local/tmp 因为所有app都对这个目录有可读权限

[debug] Failed to open /proc/self/mem

image

检查系统是否在安卓14以下

检查面具模块是否刷入

Error :access violation accessing 0x0

image

检查参数数量等是否传入正确

最后一个参数保证是6 或者0

参数一定要正确

感谢群友提供的图 !

image

About

vmtrace的发布仓库,相关so 调用脚本例子都会放在里面

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published