i茅台app逆向分析frida反调试

文章仅供思路参考,请勿用作非法攻击

环境:

i茅台 1.3.7

frida 14.2.17

安卓 9 系统


frida注入

常规frida不注入任何脚本

frida -U -f com.moutai.mall --no-pause
    / _  |   Frida 14.2.17 - 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/
Spawned `com.moutai.mall`. Resuming main thread!                        
[MI 8::com.moutai.mall]-> Process terminated
[MI 8::com.moutai.mall]->

这种情况就是有frida反调试,frida的反调试可以写在java层或者so层,搜罗网上的方法,比较

普遍的就是:使用葫芦娃版本的frida、改frida_server的名称,修改frida_server的端口,文章中的frida_server均已满足以上条件,情况比较严峻。

反调试定位:

这个app是有壳的,防护大概率会是在so层,毕竟java层的反调试已经过时了,我们可以通过hook安卓系统的libdl.so中的android_dlopen_ext来定位问题出现在哪个so,定位到具体so再定位so里面的反调试线程,找出来反调试线程最终把反调试线程替换成空函数以达到绕过frida检测的目的,以下是hook 安卓系统libdl.so中的android_dlopen_ext函数代码

function hook_dlopen(soName = '') {
    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();
                    console.log(path);
                    
                }
            }
        }
    );
}

setImmediate(hook_dlopen,"");

 以上hook代码的作用用于定位反调试出现在哪个so文件

└─# frida -U -f com.moutai.mall -l imoutai.js --no-pause
     ____
    / _  |   Frida 14.2.17 - 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/
Spawned `com.moutai.mall`. Resuming main thread!                        
[MI 8::com.moutai.mall]-> /system/framework/oat/arm64/org.apache.http.legacy.boot.odex
/data/app/com.moutai.mall-ZqwkhQsJ0Sxyv7X-FRkGlw==/oat/arm64/base.odex
/data/app/com.moutai.mall-ZqwkhQsJ0Sxyv7X-FRkGlw==/lib/arm64/libnesec.so
Process terminated
[MI 8::com.moutai.mall]->

Thank you for using Frida!

 通过将js代码注入到目标app,根据以上显示可以发现 libnesec.so 的可能性非常大,注入多次后仍然是停留在这个so,说明这个so内部有函数做了反调试处理。我们修改修改js代码,以便能定位反调试线程,新的js代码如下:

var soaddr = null;
function hook_dlopen(soName = '') {
    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(soName) != -1) {
                        
                        this.hook = true;
                        
                    }
                    console.log(path);
                    
                }
            },
            onLeave:function(ret){
                if (this.hook = true) {
                  
                    soaddr = Module.findBaseAddress("libnesec.so");
                    hook_pthread_create();
                }
            }
        }
    );
}
function printNativeStack(context, name) {
    var trace = Thread.backtrace(context, Backtracer.ACCURATE).map(DebugSymbol.fromAddress).join("\n");
   console.log(trace)
  }
function hook_pthread_create() {
    
    Interceptor.attach(Module.findExportByName("libc.so", "pthread_create"), {
        onEnter(args) {
            var func_addr = args[2]
            
            var offes = func_addr.sub(soaddr);
            console.log("The thread function address is " + offes);
           
            
            
        }
    })
}
setImmediate(hook_dlopen,"libnesec.so");

 注入以上代码返回以下

──(root💀r0env)-[~/Desktop/frida_js]
└─# frida -U -f com.moutai.mall -l imoutai.js --no-pause
     ____
    / _  |   Frida 14.2.17 - 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/
Spawned `com.moutai.mall`. Resuming main thread!                        
[MI 8::com.moutai.mall]-> /system/framework/oat/arm64/org.apache.http.legacy.boot.odex
/data/app/com.moutai.mall-ZqwkhQsJ0Sxyv7X-FRkGlw==/oat/arm64/base.odex
/data/app/com.moutai.mall-ZqwkhQsJ0Sxyv7X-FRkGlw==/lib/arm64/libnesec.so
The thread function address is 0x8abb4
The thread function address is 0x8abb4
The thread function address is 0x8abb4
The thread function address is 0x7598c
The thread function address is 0x7598c
The thread function address is 0x7598c
The thread function address is 0x6e348
The thread function address is 0x6e348
The thread function address is 0x6e348
The thread function address is 0x9baef4fc
The thread function address is 0x9baef4fc
The thread function address is 0x9baef4fc
The thread function address is 0x8ac9c
The thread function address is 0x8ac9c
The thread function address is 0x8ac9c
The thread function address is 0x88e04
The thread function address is 0x88e04
The thread function address is 0x88e04
Process terminated
[MI 8::com.moutai.mall]->

 根据以上结果配合分析得知:0x88e04 这个偏移地址就是frida反调试线程,我们再次修改js代码为如下,把反调试的函数替换成空的函数,达到绕过的目的。

var soaddr = null;
function hook_dlopen(soName = '') {
    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(soName) != -1) {
                        
                        this.hook = true;
                        
                    }
                    console.log(path);
                    
                }
            },
            onLeave:function(ret){
                if (this.hook = true) {
                  
                    soaddr = Module.findBaseAddress("libnesec.so");
                    hook_pthread_create();
                }
            }
        }
    );
}
function printNativeStack(context, name) {
    var trace = Thread.backtrace(context, Backtracer.ACCURATE).map(DebugSymbol.fromAddress).join("\n");
   console.log(trace)
  }
function hook_pthread_create() {
    
    Interceptor.attach(Module.findExportByName("libc.so", "pthread_create"), {
        onEnter(args) {
            let func_addr = args[2]
            
            var offes = func_addr.sub(soaddr);
  
            if (offes == 0x88e04) {
            
                
                Interceptor.replace(func_addr,new NativeCallback(function(){
                    console.log("0x891b8 replaces");
                },'void',[]));
                
            }
            
            
        }
    })
}
setImmediate(hook_dlopen,"libnesec.so");
─# frida -U -f com.moutai.mall -l imoutai.js --no-pause
     ____
    / _  |   Frida 14.2.17 - 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/
Spawned `com.moutai.mall`. Resuming main thread!                        
[MI 8::com.moutai.mall]-> /system/framework/oat/arm64/org.apache.http.legacy.boot.odex
/data/app/com.moutai.mall-ZqwkhQsJ0Sxyv7X-FRkGlw==/oat/arm64/base.odex
/data/app/com.moutai.mall-ZqwkhQsJ0Sxyv7X-FRkGlw==/lib/arm64/libsecsdk.so
/data/app/com.moutai.mall-ZqwkhQsJ0Sxyv7X-FRkGlw==/lib/arm64/libc++_shared.so
/data/app/com.moutai.mall-ZqwkhQsJ0Sxyv7X-FRkGlw==/lib/arm64/libmmkv.so
/data/app/com.moutai.mall-ZqwkhQsJ0Sxyv7X-FRkGlw==/lib/arm64/libproperty_get.so
/data/app/com.moutai.mall-ZqwkhQsJ0Sxyv7X-FRkGlw==/lib/arm64/libBugly.so
/data/app/com.moutai.mall-ZqwkhQsJ0Sxyv7X-FRkGlw==/lib/arm64/libCryptoSeed.so
/system/framework/oat/arm64/gson.odex
/data/dalvik-cache/arm64/system@app@MiuiContentCatcher@MiuiContentCatcher.apk@classes.dex
/data/dalvik-cache/arm64/system@app@CatcherPatch@CatcherPatch.apk@classes.dex
/vendor/lib64/hw/gralloc.sdm845.so
/vendor/lib64/hw/android.hardware.graphics.mapper@2.0-impl-qti-display.so
[MI 8::com.moutai.mall]-> Frida
{
    "version": "14.2.17"
}
[MI 8::com.moutai.mall]->

完结:

至此本文就结束了,大佬轻喷.。。。交流群:613707164

 

  • 6
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
要使用 Frida 进行第三方应用程序的动态调试,需要进行以下步骤: 1. 手机或模拟器需要具有 root 权限。 2. 在手机或模拟器中安装 Frida Server。可以下载最新版的 Frida Server,并将其推送到 /data/local/tmp 目录下,然后在命令行中运行以下命令启动 Frida Server: ``` adb push frida-server-14.2.18-android-x86 /data/local/tmp/frida-server adb shell chmod 755 /data/local/tmp/frida-server adb shell /data/local/tmp/frida-server & ``` 其中,frida-server-14.2.18-android-x86 是 Frida Server 的文件名,根据具体的情况可能会有所不同。 3. 在 Frida 的命令行中使用以下命令连接到设备: ``` frida -U ``` 4. 在 Frida 的命令行中使用以下命令列出设备上的应用程序: ``` frida-ps -U ``` 5. 选择需要进行动态调试的应用程序,并记录其进程 ID。 6. 在 Frida 的命令行中使用以下命令启动应用程序,并在其进程中注入 Frida: ``` frida -U -p 进程ID -l hook.js --no-pause ``` 其中,进程ID 是第 5 步中记录的应用程序的进程 ID,hook.js 是 Hook 代码所在的 JavaScript 文件。 7. 在 Android Studio 中编写 Hook 代码,并将其保存为 hook.js 文件。 8. 在 Hook 代码中使用 Java.use() 或 Java.choose() 等函数来 Hook 应用程序中的类和方法。 9. 在命令行中运行第 6 步中的命令,等待应用程序启动,然后在 Android Studio 的 Logcat 中查看 Hook 的结果。 需要注意的是,在使用 Frida 进行第三方应用程序的动态调试时,需要注意遵守法律法规和伦理道德,不要进行非法活动。
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值