首页 > 其他分享 >【Android 逆向】frida 检测绕过

【Android 逆向】frida 检测绕过

时间:2023-11-23 14:01:18浏览次数:26  
标签:function 逆向 console hook pthread var frida Android com

参考地址:

1. aaa.apk 安装到手机,是一个叫玩吧的应用

./hooker
......
23248  浏 览 器                                     com.browser2345_oem                             
32541  玩吧                                        com.wodi.who                                    
 2447  电话和短信存储                                   com.android.providers.telephony                 
 2447  电话服务                                      com.android.phone                               
 3264  电量和性能                                     com.miui.powerkeeper  
......

2. 启动hluda版frida server hluda-server-14.2.13-android-arm64 绕过一些对frida特征的检查

执行 frida -Uf com.wodi.who --no-pause,直接崩溃退出

Spawned `com.wodi.who`. Resuming main thread!                           
[MI 5X::com.wodi.who]-> Process terminated
[MI 5X::com.wodi.who]->

说明有对frida 附着到进程存在检测

3. 常用检测有 对 TracerPid 的检测,参考r0trace 的方案进行绕过

var ByPassTracerPid = function () {
    var fgetsPtr = Module.findExportByName("libc.so", "fgets");
    var fgets = new NativeFunction(fgetsPtr, 'pointer', ['pointer', 'int', 'pointer']);
    Interceptor.replace(fgetsPtr, new NativeCallback(function (buffer, size, fp) {
        var retval = fgets(buffer, size, fp);
        var bufstr = Memory.readUtf8String(buffer);
        if (bufstr.indexOf("TracerPid:") > -1) {
            Memory.writeUtf8String(buffer, "TracerPid:\t0");
            console.log("tracerpid replaced: " + Memory.readUtf8String(buffer));
        }
        return retval;
    }, 'pointer', ['pointer', 'int', 'pointer']));
};

日志

Spawned `com.wodi.who`. Resuming main thread!                           
[MI 5X::com.wodi.who]-> tracerpid replaced: TracerPid:  0
Process terminated
[MI 5X::com.wodi.who]->

还是不行,看来还有别的地方检测

4.尝试hook pthread_create 来看一下哪里调用到了它

function hook_func() {
    var pthread_creat_addr = Module.findExportByName("libc.so", "pthread_create")
    Interceptor.attach(pthread_creat_addr,{
        onEnter(args){
            console.log("call pthread_create...")
            let func_addr = args[2]
            console.log("The thread function address is " + func_addr)
            console.log('pthread_create called from:\n' 
            + Thread.backtrace(this.context, Backtracer.ACCURATE)
            .map(DebugSymbol.fromAddress)
            .join('\n')
             + '\n');
        }
    })
}

执行日志:

call pthread_create...
The thread function address is 0xc0512129
The libmsaoaidsec.so base 0xc0501000
pthread_create called from:
0xc05123fd libmsaoaidsec.so!0x113fd
0xc0511ab7 libmsaoaidsec.so!0x10ab7
0xc0511bc1 libmsaoaidsec.so!0x10bc1
0xc050d5b9 libmsaoaidsec.so!_init+0x1ac
0xec63662b

......
tracerpid replaced: TracerPid:  0
Process terminated

可以看到 libmsaoaidsec.so 执行了0x113fd 后好像就出问题了,而且这个是在_init+0x1ac,很值得怀疑,看一下反汇编的代码

0xc0512129 - 0xc0501000 = 0x11129
可以看到这里看起来一个线程搞事情

int sub_113E0()
{
  _DWORD *v0; // r4
  pthread_t v2; // [sp+0h] [bp-10h] BYREF
  int v3; // [sp+4h] [bp-Ch]

  v0 = off_1FC04;
  v3 = *(_DWORD *)off_1FC04;
  pthread_create(&v2, 0, (void *(*)(void *))sub_11128, 0);
  return *v0 - v3;
}

那么hook 掉这个 sub_11128 ,让他啥也不干,对应偏移地址 0x000113E0

Interceptor.replace(module.base.add(0x00011128+1), new NativeCallback(function() {
        console.log("0x00011129 replace success!!!")
    }, 'void', []))

执行日志

***
*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
Build fingerprint: 'xiaomi/tiffany/tiffany:8.1.0/OPM1.171019.019/V11.0.3.0.ODBCNXM:user/release-keys'
Revision: '0'
ABI: 'arm'
pid: 12322, tid: 12322, name: com.wodi.who  >>> com.wodi.who <<<
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x32b1
    r0 0000c6dd  r1 0000008c  r2 8ea8c4cb  r3 0000023d
    r4 00000000  r5 0008d5f4  r6 00003225  r7 000001aa
    r8 dd932900  r9 ffd70784  sl 00000000  fp ffd70878
    ip ea1a962c  sp ffd6e638  lr c052bc95  pc c052bc96  cpsr 200f0030

backtrace:
    #00 pc 00001c96  /data/app/com.wodi.who-Gf4PUi4Emat5i9N3B4wFBA==/lib/arm/libmsaoaidsec.so (offset 0x12000)
    #01 pc 00001c91  /data/app/com.wodi.who-Gf4PUi4Emat5i9N3B4wFBA==/lib/arm/libmsaoaidsec.so (offset 0x12000)
***

还是崩了,说明还有地方在检测,比如这个00001c96+0x12000处,
可以看到这里在检测linker的情况,查询了符号表和字符串表,估计实在检查一些函数是否被hook,那先hooker当前这个函数

Interceptor.replace(module.base.add(0x00013AB0+1), new NativeCallback(function() {
        console.log("0x00013AB1 replace success!!!")
    }, 'void', []))

注意: Thumb指令的地址 ,hook的时候要加1,然后就ok了,进程不再崩溃,执行frida命令ok

日志

Process

tracerpid replaced: TracerPid:  0
tracerpid replaced: TracerPid:  0
[MI 5X::com.wodi.who]-> Process
{
    "arch": "arm",
    "codeSigningPolicy": "optional",
    "id": 12563,
    "pageSize": 4096,
    "platform": "linux",
    "pointerSize": 4
}
[MI 5X::com.wodi.who]-> tracerpid replaced: TracerPid:  0

全部代码

var ByPassTracerPid = function () {
    var fgetsPtr = Module.findExportByName("libc.so", "fgets");
    var fgets = new NativeFunction(fgetsPtr, 'pointer', ['pointer', 'int', 'pointer']);
    Interceptor.replace(fgetsPtr, new NativeCallback(function (buffer, size, fp) {
        var retval = fgets(buffer, size, fp);
        var bufstr = Memory.readUtf8String(buffer);
        if (bufstr.indexOf("TracerPid:") > -1) {
            Memory.writeUtf8String(buffer, "TracerPid:\t0");
            console.log("tracerpid replaced: " + Memory.readUtf8String(buffer));
        }
        return retval;
    }, 'pointer', ['pointer', 'int', 'pointer']));
};
//setImmediate(ByPassTracerPid);

function hook_dlopen(soName) {
    Interceptor.attach(Module.findExportByName(null, "dlopen"),
        {
            onEnter: function (args) {
                var pathptr = args[0];
                if (pathptr !== undefined && pathptr != null) {
                    var path = ptr(pathptr).readCString();
                    if (path.indexOf(soName) >= 0) {
                        this.is_can_hook = true;
                    }
                }
            },
            onLeave: function (retval) {
                if (this.is_can_hook) {
                    console.log("hook start...");
                    hook_func()
                }
            }
        }
    );
 
    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) >= 0) {
                        this.is_can_hook = true;
                    }
                }
            },
            onLeave: function (retval) {
                if (this.is_can_hook) {
                    console.log("hook start...");
                    hook_func()
                }
            }
        }
    );
}

function hook_func() {
    var pthread_creat_addr = Module.findExportByName("libc.so", "pthread_create")
    Interceptor.attach(pthread_creat_addr,{
        onEnter(args){
            console.log("call pthread_create...")
            let func_addr = args[2]
            console.log("The thread function address is " + func_addr)
 
            let libmsaoaidsec = Process.findModuleByName("libmsaoaidsec.so")
            if (libmsaoaidsec != null){
                console.log("The libmsaoaidsec.so base " + libmsaoaidsec.base)
                bypass_thread(libmsaoaidsec)
            }

            console.log('pthread_create called from:\n' 
            + Thread.backtrace(this.context, Backtracer.ACCURATE)
            .map(DebugSymbol.fromAddress)
            .join('\n')
             + '\n');
        }
    })
}

function bypass_thread(module) {
    // Interceptor.replace(module.base.add(0x0000FA98+1), new NativeCallback(function() {
    //     console.log("0x0000FA99 replace success!!!")
    // }, 'void', []))
    
    Interceptor.replace(module.base.add(0x00011128+1), new NativeCallback(function() {
        console.log("0x00011129 replace success!!!")
    }, 'void', []))

    
P
}

function main() {
    ByPassTracerPid()
    hook_dlopen("libc.so")
}

setImmediate(main)

JAVASCRIPT 折叠 复制 全屏



标签:function,逆向,console,hook,pthread,var,frida,Android,com
From: https://blog.51cto.com/kuangke/8528950

相关文章

  • 【Android R】manualTests#com.android.cts.verifier.security.FingerprintBoundKeysT
    异常日志:11-1219:24:47.64953875387DAndroidRuntime:ShuttingdownVM11-1219:24:47.67153875387EAndroidRuntime:FATALEXCEPTION:main11-1219:24:47.67153875387EAndroidRuntime:Process:com.android.cts.verifier,PID:538711-1219:24:47.6715387......
  • 使用 Android Studio 开发一款弹钢琴app
    A.项目描述本项目主要实现了【钢琴键盘的模拟】、【弹奏引导】以及【乐曲库】等功能。钢琴键盘模拟:提供全尺寸键盘,并且根据用户的喜好来调整键盘的颜色样式。弹奏引导:用户可以根据键盘上的提示符号......
  • android.content.res.Resources$NotFoundException: String resource ID #0x1
    在Android开发中如果出现android.content.res.Resources$NotFoundException:StringresourceID#0x1这样的错误,你想也不用想,一定是Textview控件显示数据出了问题:mTextview.setText(这里的传入的数据一定写成int类型了)。我们需要做的是eg:mTextview.setText(1+""),也就是参数转......
  • android studio 添加按钮事件实现加一操作
    androidstudio添加按钮事件实现加一操作要在AndroidStudio中为按钮添加一个加一(+1)的操作,你可按照下列步骤实现:通过在XML布局中添加按钮,导入一个Button组件: XML复制代码<Buttonandroid:id="@+id/add_button"android:layout_width="wrap_content"andro......
  • 深入Android多线程编程与性能优化
    引言在上一篇的入门篇中,我们对Android线程的基础概念和多线程编程模型有了初步了解。本篇将深入探讨多线程编程技术和性能优化策略,以提升应用的效率和响应性。高级多线程编程技术使用线程池管理线程线程池是一组预先创建的线程,用于执行任务。通过使用线程池,可以避免不断创建和销毁......
  • Android 的PAI 简介
    PAI简介在Google的Android操作系统中,PAI(PreinstalledAppsInfrastructure)预安装程序基础设施是指在设备出厂时预先安装在系统中的一组应用程序。这些应用程序通常是由设备制造商或运营商选择的,并且它们在设备启动时就已经存在,用户可以在使用设备时直接访问这些应用。预安装介绍......
  • 作为一个Android初级开发工程师,该如何进阶?
    前言现今Android行业初级人才已逐渐饱和化,但中高级人才却依旧很稀缺,身边HR朋友经常遇到的情况是:100份简历里只有2、3个比较合适的候选人,大部分的人都是不合格的!有97%的Android技术人都会面临这些困境(或许也是你的困惑):缺乏技术广度和深度:如果你长期在小型软件公司或外包工......
  • 弹钢琴 app,Android 开发实战
    A.项目描述本项目主要实现了【钢琴键盘的模拟】、【弹奏引导】以及【乐曲库】等功能。钢琴键盘模拟:提供全尺寸键盘,并且根据用户的喜好来调整键盘的颜色样式。弹奏引导:用户可以根据键盘上的提示符号......
  • Android 11 -- 强制清理app后台,关于权限引发的问题
    需求:发现一个第三方应用,点击最近任务,在清理后台的界面没办法将它彻底杀死android11的最近任务部分在launcher3里面quickstep里面quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java在这个里面添加强制清理app的方法privatevoidremov......
  • Android 11 -- 关于dialog和悬浮窗导致SystemUI状态栏下拉频繁闪烁(窗口焦点问题)
    bug描述:如果当前app是全屏的属性,导致状态栏隐藏且有dialog弹出时,这个情况下想下拉显示状态栏,会导致状态栏频繁闪烁。//services/core/java/com/android/server/wm/DisplayPolicy.java//更新系统状态栏的属性intupdateSystemUiVisibilityLw(){//Ifthereisnow......