Git Product home page Git Product logo

interruptor's Introduction

Interruptor

ci

Work In Progess

The home for Interruptor, a human-friendly interrupts hook library based on Frida's Stalker

Interruptor is the interrupts/systemcall hooking system from Dexcalibur.

Quick start for Android app (could not work as is with obfuscated app) :

frida --codeshare FrenchYeti/android-arm64-strace -U -f YOUR_BINARY

If you like it, please consider to buy 💰 Dexcalibur Pro or 💖 sponsor me. Sponsor encourage me to free parts of Dexcalibur Pro and spend more free time on such projects :)

The purpose of this library is to provide to Frida users, a rich API able to produce strace-like trace + hook + configurable syscall args API.

It provides by default some useful features such as :

  • File Descriptor lookup (to retrieve path)
  • Bitmap parsing to have humean-friendly output
  • Syscall hook using Frida's Interceptor style
  • Better api to trace/change syscall args before/after
  • Filterable modules and syscalls
  • Coverage generation

Full documentation of the API is now available

1. How to use it

Interruptor can be used by following different approach. I Hope you will be able to find the best one for you :

  • A. Interruptor as NPM package in your hooking project
  • B. Importing minified file per architecture/os
  • C. Using Frida's CodeShare (not yet configurable, less suitable for tampering)
  • C. From source

Case A : Using Interruptor package

See it on NPM

It is the BEST and more reliable way to use Interruptor

This method require Frida >= 16.x is you write your hook in Typescript.

Basically, create a new folder for your hooks or move into your workspace :

mkdir my_workspace && cd my_workspace

And install the package :

npm install @reversense/interruptor

After successful install, you can create a basic script (script.ts) like it (TypeScript) :

import target from '@reversense/interruptor/index.linux.arm64.js';

const Interruptor = target.LinuxArm64({});

Interruptor.newAgentTracer({
    followThread: true,
    scope: {
        syscalls: {
            exclude:  [/clock_gettime/]
        },
        modules: {
            exclude: [/linker/]
        }
    },
    onStart: function(){
        console.log("Entering into lib")
    }
}).start();

Then, just launch your frida script like this :

frida -U -l ./script.ts -f <YOUR_APP>

May be you noted TS script is passed directly to frida instead of frida-compile, such thing is possible with Frida >= 16.x .

Case B : From minified files

Requirements :

  • frida

Download latest release for your architecture into your working directory, and do:

import target from './index.linux.arm64.min.js';
import {DebugUtils} from "./src/common/DebugUtils.js";

const Interruptor = target.LinuxArm64({});

Interruptor.newAgentTracer({
    followThread: true,
    scope: {
        syscalls: {
            exclude:  [/clock_gettime/]
        },
        modules: {
            exclude: [/linker/]
        }
    }
}).start();

Time to deploy hooks can be configured to be when a particular library is loaded. See options below.

Case C : Using Frida's Codeshare (not yet configurable)

Warning : this methods don't allow you to configure Interruptor. So, tracing of obfuscated or multi-threaded application could fail.

This method is only provided for linux/arm64 and training purpose.

frida --codeshare FrenchYeti/android-arm64-strace -f YOUR_BINARY

Case D : From source

Requirements :

  • frida

Don't be afraid by dependencies : Interruptor has only common dev dependencies to provide types and unit test features.

Download or clone the repository, and install it

git clone https://github.com/FrenchYeti/interruptor
cd interruptor
npm install
npm run build

When it is done, just copy one of examples into repository root folder :

cp ./examples/android/simple_trace.ts .

And finally :

frida -U -l ./simple_strace.arm64.ts -f <PACKAGE> 

2. Examples

2.A Simple tracing

With recent version (> 0.2)

Simple tracing without hook from attach moment, with excluded module and syscall (by name)

import target from '@reversense/interruptor/index.linux.arm64.js';

const Interruptor = target.LinuxArm64({});

// better results, when app is loaded
Java.perform(()=>{
    Interruptor.newAgentTracer({
        scope: {
            syscalls: { exclude:  ["clock_gettime"] },
            modules: { exclude: [/linker64/] }
        }
    }).start();
});

With version <= 0.2

Simple tracing without hook from attach moment, with excluded module and syscall (by name)

var Interruptor = require('./android-arm64-strace.min.js').target.LinuxArm64();

// better results, when app is loaded
Java.perform(()=>{
    Interruptor.newAgentTracer({
        exclude: {
            modules: ["linker64"],
            syscalls: ["clock_gettime"]
        }
    }).start();
});

Output :

Output :

	------- [TID=4407][libutils.so][0x76d9fd6388] Thread routine start -------
	[INTERRUPTOR][STARTING] Tracing thread 4407 []
	[STARTING TRACE] UID=1 Thread 4407
 [TID=4407] [/system/lib64/libc.so +0x630]   setpriority (   which = NULL ,  who = 0x0 ,  ioprio = 0x0  )    > 0x0
 [TID=4407] [/system/lib64/libc.so +0x928]   openat (   dfd = AT_FDCWD  ,  filename = /proc/4407/timerslack_ns ,  flags = O_RDONLY | O_WRONLY | O_CLOEXEC ,  mode =   )    > (FD) 0x1f
 [TID=4407] [/system/lib64/libc.so +0x990]   write (   fd = 31  /proc/4407/timerslack_ns   ,  buf = 50000 ,  size = 0x5  )    > 0x5
 [TID=4407] [/system/lib64/libc.so +0x6d0]   close (   fd = 31  /proc/4407/timerslack_ns    )    > 0x0
 [TID=4407] [/system/lib64/libc.so +0x270]   prctl (   opt = PR_SET_NAME ,  arg2 = 0x7651d1d560 ,  arg3 = 0x0 ,  arg4 = 0x0 ,  arg5 = 0x0  )    > 0x0
 [TID=4407] [/system/lib64/libc.so +0x1b0]   mprotect (   addr = 0x7641dae000 ,  size = 0x1000 ,  prot = PROT_NONE  )    > 0 SUCCESS
 [TID=4407] [/system/lib64/libc.so +0xf0]   madvise (   addr = 0x7641dae000 ,  size = 0xfb000 ,  behavior = MADV_DONTNEED  )    > 0 SUCCESS
 [TID=4407] [/system/lib64/libc.so +0x928]   openat (   dfd = AT_FDCWD  ,  filename = /dev/ashmem ,  flags = O_RDONLY | O_RDWR | O_CLOEXEC ,  mode =   )    > (FD) 0x1f
 [TID=4407] [/system/lib64/libc.so +0xd90]   fstat (   fd = 31  /dev/ashmem   ,  *statbuf = 0x7641ea9e68  )    > 0x0
 [TID=4407] [/system/lib64/libc.so +0x910]   ioctl (   fd = 31  /dev/ashmem   ,  cmd = 0x41007701 ,  arg = 0x7641ea9f38  )    > 0x0
 [TID=4407] [/system/lib64/libc.so +0x910]   ioctl (   fd = 31  /dev/ashmem   ,  cmd = 0x40087703 ,  arg = 0x2000  )    > 0x0
 [TID=4407] [/system/lib64/libc.so +0x180]   mmap (   start_addr = 0x0 ,  size = 0x2000 ,  prot = PROT_READ | PROT_WRITE ,  flags = MAP_PRIVATE ,  fd = undefined ,  offset = 0x0  )    > 0x76599ee000 SUCCESS
 [TID=4407] [/system/lib64/libc.so +0x6d0]   close (   fd = 31  /dev/ashmem    )    > 0x0
 [TID=4407] [/system/lib64/libc.so +0x1b0]   mprotect (   addr = 0x12f80000 ,  size = 0x40000 ,  prot = PROT_READ | PROT_WRITE  )    > 0 SUCCESS
 [TID=4407] [/system/lib64/libc.so +0x8e0]   getpriority (   which = NULL ,  who = 0x0  )    > 0x14
 [TID=4407] [/system/lib64/libc.so +0x270]   prctl (   opt = PR_SET_NAME ,  arg2 = 0x7641eaa148 ,  arg3 = 0x343a7265646e6942 ,  arg4 = 0x315f363833 ,  arg5 = 0x28  )    > 0x0
 [TID=4407] [/system/lib64/libc.so +0xf70]   getuid (  )    > 10089
 [TID=4407] [/system/lib64/libc.so +0x910]   ioctl (   fd = 12  undefined   ,  cmd = 0xc0306201 ,  arg = 0x7641eaa2b8  )    > 0x0
 [TID=4407] [/system/lib64/libc.so +0x180]   mmap (   start_addr = 0x0 ,  size = 0xfe000 ,  prot = PROT_READ | PROT_WRITE ,  flags = MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE ,  fd = undefined ,  offset = 0x0  )    > 0x7641263000 SUCCESS
 [TID=4407] [/system/lib64/libc.so +0x1b0]   mprotect (   addr = 0x7641263000 ,  size = 0x1000 ,  prot = PROT_NONE  )    > 0 SUCCESS
 [TID=4407] [/system/lib64/libc.so +0x270]   prctl (   opt = PR_SET_VMA ,  arg2 = 0x0 ,  arg3 = 0x7641263000 ,  arg4 = 0x1000 ,  arg5 = 0x76de1b64c5  )    > 0x0
 [TID=4407] [/system/lib64/libc.so +0x180]   mmap (   start_addr = 0x0 ,  size = 0x5000 ,  prot = PROT_NONE ,  flags = MAP_PRIVATE | MAP_ANONYMOUS ,  fd = undefined ,  offset = 0x0  )    > 0x76599e9000 SUCCESS
 [TID=4407] [/system/lib64/libc.so +0x270]   prctl (   opt = PR_SET_VMA ,  arg2 = 0x0 ,  arg3 = 0x76599e9000 ,  arg4 = 0x5000 ,  arg5 = 0x76de1b62f9  )    > 0x0
 [TID=4407] [/system/lib64/libc.so +0x1b0]   mprotect (   addr = 0x76599ea000 ,  size = 0x3000 ,  prot = PROT_READ | PROT_WRITE  )    > 0 SUCCESS
 [TID=4407] [/system/lib64/libc.so +0x270]   prctl (   opt = PR_SET_VMA ,  arg2 = 0x0 ,  arg3 = 0x76599ea000 ,  arg4 = 0x3000 ,  arg5 = 0x76de1b633b  )    > 0x0
 [TID=4407] [/system/lib64/libc.so +0x1ca8]   clone (   unsigned long = 0x3d0f00 ,  unsigned long = 0x76413604e0 ,  int * = 0x7641360500 ,  int * = 0x7641360588 ,  unsigned long = 0x7641360500  )    > 0x1139
 [TID=4407] [/system/lib64/libc.so +0x2c]   futex (   word = 0x7641360570 ,  op = FUTEX_WAKE_PRIVATE ,  u32 val = 0x1 ,  *utime = 0x0 ,  u32 *uaddr2 = 0x0 ,  u32 val3[ = 0x0  )    > 0x1
 [TID=4407] [/system/lib64/libc.so +0x2c]   futex (   word = 0x7659b1c248 ,  op = FUTEX_WAKE_PRIVATE ,  u32 val = 0x7fffffff ,  *utime = 0x0 ,  u32 *uaddr2 = 0x0 ,  u32 val3[ = 0x0  )    > 0x0

	------- [TID=4409][libutils.so][0x76d9fd6388] Thread routine start -------
	[INTERRUPTOR][STARTING] Tracing thread 4409 []
	[STARTING TRACE] UID=2 Thread 4409
 [TID=4409] [/system/lib64/libc.so +0x630]   setpriority (   which = NULL ,  who = 0x0 ,  ioprio = 0x0  )    > 0x0
 [TID=4409] [/system/lib64/libc.so +0x928]   openat (   dfd = AT_FDCWD  ,  filename = /proc/4409/timerslack_ns ,  flags = O_RDONLY | O_WRONLY | O_CLOEXEC ,  mode =   )    > (FD) 0x1f
 [TID=4409] [/system/lib64/libc.so +0x990]   write (   fd = 31  /proc/4409/timerslack_ns   ,  buf = 50000 ,  size = 0x5  )    > 0x5
 [TID=4409] [/system/lib64/libc.so +0x6d0]   close (   fd = 31  /proc/4409/timerslack_ns    )    > 0x0
 [TID=4409] [/system/lib64/libc.so +0x270]   prctl (   opt = PR_SET_NAME ,  arg2 = 0x765364f010 ,  arg3 = 0x0 ,  arg4 = 0x0 ,  arg5 = 0x0  )    > 0x0
 [TID=4409] [/system/lib64/libc.so +0x1b0]   mprotect (   addr = 0x7641264000 ,  size = 0x1000 ,  prot = PROT_NONE  )    > 0 SUCCESS
 [TID=4409] [/system/lib64/libc.so +0xf0]   madvise (   addr = 0x7641264000 ,  size = 0xfb000 ,  behavior = MADV_DONTNEED  )    > 0 SUCCESS
 [TID=4409] [/system/lib64/libc.so +0x928]   openat (   dfd = AT_FDCWD  ,  filename = /dev/ashmem ,  flags = O_RDONLY | O_RDWR | O_CLOEXEC ,  mode =   )    > (FD) 0x1f
 [TID=4409] [/system/lib64/libc.so +0xd90]   fstat (   fd = 31  /dev/ashmem   ,  *statbuf = 0x764135fe68  )    > 0x0
 [TID=4409] [/system/lib64/libc.so +0x910]   ioctl (   fd = 31  /dev/ashmem   ,  cmd = 0x41007701 ,  arg = 0x764135ff38  )    > 0x0
 [TID=4409] [/system/lib64/libc.so +0x910]   ioctl (   fd = 31  /dev/ashmem   ,  cmd = 0x40087703 ,  arg = 0x2000  )    > 0x0
 [TID=4409] [/system/lib64/libc.so +0x180]   mmap (   start_addr = 0x0 ,  size = 0x2000 ,  prot = PROT_READ | PROT_WRITE ,  flags = MAP_PRIVATE ,  fd = undefined ,  offset = 0x0  )    > 0x7656380000 SUCCESS
 [TID=4409] [/system/lib64/libc.so +0x6d0]   close (   fd = 31  /dev/ashmem    )    > 0x0
 [TID=4409] [/system/lib64/libc.so +0x1b0]   mprotect (   addr = 0x12fc0000 ,  size = 0x40000 ,  prot = PROT_READ | PROT_WRITE  )    > 0 SUCCESS

More complete example are provided into examples directory.

2.B Simple tracing with hooked "read" syscall and dynamic loading

Interruptor.newAgentTracer({
    scope: {
        syscalls: { exclude:  ["clock_gettime"] }
    },
    svc: {
         read: {
             onLeave: function(ctx){
                 let res = Memory.scanSync(ctx.x1, ctx.x2.toInt32(), Interruptor.utils().toScanPattern('frida'));
                 if(res.length > 0){
                     res.map( m => m.address.writeByteArray([0x41,0x41,0x41,0x41,0x41]));
                     console.log("remove 'frida' pattern from resulting buffer");
                 }
             }
         }
    }
}).startOnLoad(/<YOUR_LIB>/g); 

2.C Simple tracing with coverage

Interruptor.newAgentTracer({
    scope: {
        syscalls: { exclude:  ["clock_gettime"] }
    },
    coverage: {
        enabled: true,
        fname: "/data/data/<YOUR_APP>/test.drcov",
        stops: {
            count: 2000 // stop after 2000 basic blocks captured
        }
    }
}).startOnLoad(/<YOUR_LIB>/g);

3. Supports

Architectures

  • Aarch64 : SVC (syscall), HVC (WiP, hypervisor)
  • x64 : SYSCALL

APIs

  • Linux kernel API (syscall)

4. Roadmap

How to help ?

The following links enumerates Linux syscall for several architectures, feel free to extend Interruptor and do a PR :)

https://marcin.juszkiewicz.com.pl/download/tables/syscalls.html

5. Documentation

5.A Create a new agent

First, you need to get the tracer factory adapted to your OS/Architecture : For now only "LinuxArm64()" is available.

var Interruptor = require('../dist/index.js').target.LinuxArm64();

Next step is to intanciante a tracer with a specific options. Options are not mandatory but can change a lot the behavior and output.

Interruptor.newAgentTracer( /* opts */);

A full list of options can be found into the next section.

Final step, choose when you want to start to trace :

  • A. When frida script is executed
var Interruptor = require('../dist/index.js').target.LinuxArm64();

Interruptor.newAgentTracer( /* opts */).start();
  • B. The first time a module is opened by the linker
var Interruptor = require('../dist/index.js').target.LinuxArm64();

Interruptor.newAgentTracer( /* opts */).startOnLoad(/my_lib\.so$/g);
  • C. From your hooks
var Interruptor = require('../dist/index.js').target.LinuxArm64();

Interceptor.attach( /* ... */,{
    onEnter: function(){
        Interruptor.newAgentTracer( /* opts */).start();
    }
})

5.B Options

All options are optional, except some explicited options Below, a complete overview of options :

{
    followFork: TRUE | FALSE ] // TODO
    followThread: TRUE | FALSE ] // TODO
    tid: <Thread ID>,
    pid: <PID>,
    onStart: <callback function>,
    exclude: {
        syscalls: [ ... syscall names ... ], // "read", ...
        modules: [ ... module names ... ], // "linker64" ...
        svc: [ ... SVC number ...], // 0x1e, ...
        hvc: [ ... HVC number ...]
    },
    // coverage options
    coverage: {
        enabled = true,
        flavor = "dr", // not supported
        fname = "/data/data/my_app/drcov.dat", // MANDATORY
        stops = 2000 // MANDATORY
    },
    // output options (partially implemented)
    output: {
        flavor: "dxc", // "strace" is coming
        tid: true,
        pid: false,
        module: true,
        dump_buff: true, // dump buffer when ptr+size are known 
        highlight: {
            syscalls: []
        }
    },
    // hooks
    svc: {
        [syscall_text_name]: {
            onEnter: function(pContext){
            
            },
            onLeave: function(pContext){
            
            }
        }
    }
}

5.B.1 Filtering

! Important !

When a system is excluded, it is not hooked and printed. By consequence, some feature can not work properly such as file descriptor lookup when "openat" is excluded.

All interruption types can be filtered using at least the interruption number. Additionnally, Modules and System calls can be filtered by name (string pattern or regexp) or by properties (using a filtering function).

Interruptor.newAgentTracer({
    followThread: false,
    include: {
        modules: ["libc.so"],
        syscalls: [/^get/,"read","openat","close",/^m/]
    },
    exclude: {
        syscalls: [ /time$/]
    },
    output: {
        tid: true,
        inst: true,
        module: true
    }
}).start();

Modules and System calls are filtering by following one of these tree ways : Hook/trace only instructions

  • from a list of mapped modules
  • from modules not included into "exclude list" of mapped modules
  • from included modules - excluded modules
include: {
    syscalls: [
        "read",
        "openat",
        "close",
        /^m/,       // mprotect, madvise, mmap, ...
        /^get/     // getpriority, getuid, getpid,  ...
    ]
},

5.C Tracer types

There are mainly two way to hook interrupts depending of yours needs.

Agent Tracer

When you want to use only a Frida agent script (and not host script).

Limitation:

Cannot follow children/multiples processes.

Standalone Tracer [TODO]

When you need to follow children processes, or external processes. It works even if there is not link between traces processes.

In this case, the final script runs on the host and act like strace tool into the host or the device.

interruptor's People

Contributors

frenchyeti avatar kingmahmud avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

interruptor's Issues

Generate minified one-file script

Instead of using this project from sources, providing a minified JS file file for any arch/os supported should be easiest to final users.

Crash on attempting to trace any application

The crash also happens when trying to trace other applications as well. Device is a Moto G8 on stock ROM rooted via Magisk, Android 11.

$ frida -U --codeshare FrenchYeti/android-arm64-strace -f lv.amberphone.pasazieruvilciens
     ____
    / _  |   Frida 16.1.5 - 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 moto g 8  (id=ZY2282SCS6)
Spawned `lv.amberphone.pasazieruvilciens`. Resuming main thread!
[moto g 8 ::lv.amberphone.pasazieruvilciens ]-> [LINKER] Loading '/data/app/~~B24fXXQXtSHbhNpTZLJZUw==/lv.amberphone.pasazieruvilciens-6JndHQcV1kp025BvFlBZUA==/lib/arm64/librealm-jni.so'
[INTERRUPTOR][STARTING] Module '/data/app/~~B24fXXQXtSHbhNpTZLJZUw==/lv.amberphone.pasazieruvilciens-6JndHQcV1kp025BvFlBZUA==/lib/arm64/librealm-jni.so' is loading, tracer will start
[INTERRUPTOR][STARTING] Tracing thread 11412 []
[STARTING TRACE] UID=0 Thread 11412
Deploying pthread_create hook
0 1
 [TID=11412] [/apex/com.android.runtime/lib64/bionic/libc.so +0x38c]   futex (   word = 0x780fc3de40 ,  op = FUTEX_WAKE_PRIVATE ,  u32 val = 0x7fffffff ,  struct __kernel_timespec *utime = 0x0 ,  u32 *uaddr2 = 0x0 ,  u32 val3[ = 0x0  )    > 0x0
 [TID=11412] [/apex/com.android.runtime/lib64/bionic/libc.so +0x38c]   futex (   word = 0x780fc3de20 ,  op = FUTEX_WAKE_PRIVATE ,  u32 val = 0x7fffffff ,  struct __kernel_timespec *utime = 0x0 ,  u32 *uaddr2 = 0x0 ,  u32 val3[ = 0x0  )    > 0x0
Process crashed: Bad access due to invalid address

***
*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
Build fingerprint: 'motorola/rav_reteu/rav:11/RPJS31.Q4U-47-35-17/4bff0:user/release-keys'
Revision: 'pvt1'
ABI: 'arm64'
Timestamp: 2024-04-21 13:04:08+0200
pid: 11412, tid: 11412, name: sazieruvilciens  >>> lv.amberphone.pasazieruvilciens <<<
uid: 10252
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x8
Cause: null pointer dereference
    x0  0000007fe8cd7038  x1  0000000000000006  x2  0000007831111bc0  x3  0000007fe8cd6fb0
    x4  0000007fe8cd6fa0  x5  0000007882848280  x6  000000780fc3f1f0  x7  0000007fe8cd72f8
    x8  0000000000000000  x9  0000000000000000  x10 000000000000062b  x11 0000000000000001
    x12 000000780fc3e510  x13 48646e4a362d736e  x14 0000000000000000  x15 000000780fafa43c
    x16 0000000000000001  x17 0000000000000000  x18 0000007b27098000  x19 0000000000000000
    x20 0000007fe8cd7038  x21 000000780fc25000  x22 000000780fc25000  x23 000000780fc25000
    x24 00000000ffffffff  x25 000000780fc3d2f8  x26 000000780fc12fd0  x27 0000007b24405d50
    x28 000000780fc3d2f8  x29 0000007fe8cd7010
    lr  000000780faf99fc  sp  0000007fe8cd7010  pc  000000787eb960d8  pst 0000000080000000
backtrace:
      #00 pc 000000000001a0d8  <anonymous:787eb7c000>
      #01 pc 000000000031d9f8  /data/app/~~B24fXXQXtSHbhNpTZLJZUw==/lv.amberphone.pasazieruvilciens-6JndHQcV1kp025BvFlBZUA==/lib/arm64/librealm-jni.so!librealm-jni.so (offset 0x319000) (BuildId: 00148e37ca2d0eb9a73ff48909a15a181c3134eb)
      #02 pc 000000000031d9f8  /data/app/~~B24fXXQXtSHbhNpTZLJZUw==/lv.amberphone.pasazieruvilciens-6JndHQcV1kp025BvFlBZUA==/lib/arm64/librealm-jni.so!librealm-jni.so (offset 0x319000) (BuildId: 00148e37ca2d0eb9a73ff48909a15a181c3134eb)
      #03 pc 000000000031df78  /data/app/~~B24fXXQXtSHbhNpTZLJZUw==/lv.amberphone.pasazieruvilciens-6JndHQcV1kp025BvFlBZUA==/lib/arm64/librealm-jni.so!librealm-jni.so (offset 0x319000) (BuildId: 00148e37ca2d0eb9a73ff48909a15a181c3134eb)
      #04 pc 00000000000915ec  /data/app/~~B24fXXQXtSHbhNpTZLJZUw==/lv.amberphone.pasazieruvilciens-6JndHQcV1kp025BvFlBZUA==/lib/arm64/librealm-jni.so!librealm-jni.so (offset 0x8f000) (BuildId: 00148e37ca2d0eb9a73ff48909a15a181c3134eb)
      #05 pc 000000000004a0f0  /apex/com.android.runtime/bin/linker64!ld-android.so (offset 0x49000) (__dl__ZL10call_arrayIPFviPPcS1_EEvPKcPT_mbS5_+284) (BuildId: f973854810260f3568df23436074dee3)
      #06 pc 000000000004a2f0  /apex/com.android.runtime/bin/linker64!ld-android.so (offset 0x49000) (__dl__ZN6soinfo17call_constructorsEv+380) (BuildId: f973854810260f3568df23436074dee3)
      #07 pc 0000000000000e08  <anonymous:7b27f59000>
***
[moto g 8 ::lv.amberphone.pasazieruvilciens ]->

Thank you for using Frida!

The app freezes on an Emulator

arch: x64
device: Emulator from Android Studio
Tested API versions: 28 and 31

command: frida -U -f com.android.contacts -l _agent.js --no-pause

code:

const Interruptor = require('./android-x64-strace.min.js').target.LinuxX64();

Interruptor.newAgentTracer({
}).start();

The script hooks threads and prints some syscalls but the app itself freezes, seems like the main thread never resumes or something like that.

How SVC hooking is implemented

How is SVC / syscall hooking is implemented?

If someone tries to bypass Frida by using syscalls directly without libc wrapper will we detect them?
For example some packers do that

R2Pay crashes on arm64 with "Bad access due to invalid address"

It seems this crash is not produced by the RASP inside R2pay:

[14:30 edu@xps radare2]  (master)>  frida --codeshare FrenchYeti/android-arm64-strace -H 127.0.0.1:27042 -f re.pwnme --no-pause
     ____
    / _  |   Frida 15.1.14 - 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 `re.pwnme`. Resuming main thread!                               
[Remote::re.pwnme]-> [STARTING TRACE] UID=0 Thread 14474
Process crashed: Bad access due to invalid address

***
*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
Build fingerprint: 'google/walleye/walleye:11/RP1A.200720.009/6720564:user/release-keys'
Revision: 'MP1'
ABI: 'arm64'                                                                                                                                                                 
Timestamp: 2022-01-24 08:30:41-0500
pid: 14474, tid: 14474, name: re.pwnme  >>> re.pwnme <<<
uid: 10250
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x1f03e036000074
    x0  0000007c520841a4  x1  0000007c36a3c658  x2  0000007bf23b3970  x3  0000000000000001
    x4  0000007bf23b70f4  x5  0000000000000000  x6  0000000000000040  x7  7f7f7f7f7f7f7f7f
    x8  0000007ee78eb000  x9  0000007c523f8000  x10 0000007b00000007  x11 0000000000000001
    x12 0000000001120197  x13 0000007c50a5e09c  x14 0000007c522bd998  x15 0000007c522bd998
    x16 0000000000000001  x17 0000000000000000  x18 0000000000000000  x19 0000007c36a3c658
    x20 2a1f03e036000074  x21 2a1f03e036000060  x22 0000007dc2411be0  x23 0000007c520841a4
    x24 0000007d32411160  x25 0000000000000004  x26 0000007ee78eb000  x27 0000007fdec4dac8
    x28 0000000000000139  x29 0000007fdec4d4b0
    lr  0000007c520841a4  sp  0000007fdec4d470  pc  0000007c36a3cae8  pst 0000000080000000
backtrace:
      #00 pc 000000000001cae8  <anonymous:7c36a20000>
      #01 pc 00000000003411a0  /apex/com.android.art/lib64/libart.so!libart.so (offset 0x341000) (art::jit::Jit::MaybeDoOnStackReplacement(art::Thread*, art::ArtMethod*, unsigned int, int, art::JValue*)+112) (BuildId: d0f321775158ed00df284edfabf672b6)
      #02 pc 00000000003411a0  /apex/com.android.art/lib64/libart.so!libart.so (offset 0x341000) (art::jit::Jit::MaybeDoOnStackReplacement(art::Thread*, art::ArtMethod*, unsigned int, int, art::JValue*)+112) (BuildId: d0f321775158ed00df284edfabf672b6)
      #03 pc 0000000000172b88  /apex/com.android.art/lib64/libart.so!libart.so (offset 0x16a000) (void art::interpreter::ExecuteSwitchImplCpp<true, false>(art::interpreter::SwitchImplContext*)+35408) (BuildId: d0f321775158ed00df284edfabf672b6)
      #04 pc 000000000013f7d8  /apex/com.android.art/lib64/libart.so!libart.so (offset 0x13f000) (ExecuteSwitchImplAsm+8) (BuildId: d0f321775158ed00df284edfabf672b6)
      #05 pc 00000000001a22e8  /system/framework/framework.jar (android.app.ActivityThread.updateDefaultDensity)
      #06 pc 00000000003095d8  /apex/com.android.art/lib64/libart.so!libart.so (offset 0x309000) (art::interpreter::Execute(art::Thread*, art::CodeItemDataAccessor const&, art::ShadowFrame&, art::JValue, bool, bool) (.llvm.7618685802058321727)+528) (BuildId: d0f321775158ed00df284edfabf672b6)
      #07 pc 0000000000311840  /apex/com.android.art/lib64/libart.so!libart.so (offset 0x311000) (art::interpreter::ArtInterpreterToInterpreterBridge(art::Thread*, art::CodeItemDataAccessor const&, art::ShadowFrame*, art::JValue*)+200) (BuildId: d0f321775158ed00df284edfabf672b6)
      #08 pc 0000000000313b5c  /apex/com.android.art/lib64/libart.so!libart.so (offset 0x311000) (bool art::interpreter::DoCall<true, true>(art::ArtMethod*, art::Thread*, art::ShadowFrame&, art::Instruction const*, unsigned short, art::JValue*)+1692) (BuildId: d0f321775158ed00df284edfabf672b6)
      #09 pc 00000000001755f8  /apex/com.android.art/lib64/libart.so!libart.so (offset 0x16a000) (void art::interpreter::ExecuteSwitchImplCpp<true, false>(art::interpreter::SwitchImplContext*)+46272) (BuildId: d0f321775158ed00df284edfabf672b6)
      #10 pc 000000000013f7d8  /apex/com.android.art/lib64/libart.so!libart.so (offset 0x13f000) (ExecuteSwitchImplAsm+8) (BuildId: d0f321775158ed00df284edfabf672b6)
      #11 pc 000000000019dacc  /system/framework/framework.jar (android.app.ActivityThread.handleBindApplication)
      #12 pc 00000000003095d8  /apex/com.android.art/lib64/libart.so!libart.so (offset 0x309000) (art::interpreter::Execute(art::Thread*, art::CodeItemDataAccessor const&, art::ShadowFrame&, art::JValue, bool, bool) (.llvm.7618685802058321727)+528) (BuildId: d0f321775158ed00df284edfabf672b6)
      #13 pc 00000000006740c0  /apex/com.android.art/lib64/libart.so!libart.so (offset 0x674000) (artQuickToInterpreterBridge+776) (BuildId: d0f321775158ed00df284edfabf672b6)
      #14 pc 000000000013cff8  /apex/com.android.art/lib64/libart.so!libart.so (offset 0x13c000) (art_quick_to_interpreter_bridge+88) (BuildId: d0f321775158ed00df284edfabf672b6)
      #15 pc 0000000000133564  /apex/com.android.art/lib64/libart.so!libart.so (offset 0x133000) (art_quick_invoke_stub+548) (BuildId: d0f321775158ed00df284edfabf672b6)
      #16 pc 00000000001a97e8  /apex/com.android.art/lib64/libart.so!libart.so (offset 0x1a9000) (art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*)+200) (BuildId: d0f321775158ed00df284edfabf672b6)
      #17 pc 000000000055b830  /apex/com.android.art/lib64/libart.so!libart.so (offset 0x480000) (art::JValue art::InvokeWithVarArgs<art::ArtMethod*>(art::ScopedObjectAccessAlreadyRunnable const&, _jobject*, art::ArtMethod*, std::__va_list)+448) (BuildId: d0f321775158ed00df284edfabf672b6)
      #18 pc 000000000055bcf4  /apex/com.android.art/lib64/libart.so!libart.so (offset 0x480000) (art::JValue art::InvokeWithVarArgs<_jmethodID*>(art::ScopedObjectAccessAlreadyRunnable const&, _jobject*, _jmethodID*, std::__va_list)+92) (BuildId: d0f321775158ed00df284edfabf672b6)
      #19 pc 0000000000427560  /apex/com.android.art/lib64/libart.so!libart.so (offset 0x394000) (art::JNI<true>::CallNonvirtualVoidMethodV(_JNIEnv*, _jobject*, _jclass*, _jmethodID*, std::__va_list)+656) (BuildId: d0f321775158ed00df284edfabf672b6)
      #20 pc 000000000037ded8  /apex/com.android.art/lib64/libart.so!libart.so (offset 0x367000) (art::(anonymous namespace)::CheckJNI::CallMethodV(char const*, _JNIEnv*, _jobject*, _jclass*, _jmethodID*, std::__va_list, art::Primitive::Type, art::InvokeType)+2576) (BuildId: d0f321775158ed00df284edfabf672b6)
      #21 pc 000000000036c9e8  /apex/com.android.art/lib64/libart.so!libart.so (offset 0x367000) (art::(anonymous namespace)::CheckJNI::CallNonvirtualVoidMethod(_JNIEnv*, _jobject*, _jclass*, _jmethodID*, ...)+144) (BuildId: d0f321775158ed00df284edfabf672b6)
      #22 pc 0000000000002b94  /dev/re.frida.helper/frida-server-64.so (offset 0x740000)
***
[Remote::re.pwnme]->                                                                                                                                                         

Thank you for using Frida!
[14:30 edu@xps radare2]  (master)>  

Process crashed: Trace/BPT trap and Bad access due to invalid address

Galaxy s9
Android 10
kernel: 4.9
java vm: 2.1.0

index.ts

var Interruptor = require('./android-arm64-strace.min.js').target.LinuxArm64();

// better results, when app is loaded
Java.perform(()=>{
    Interruptor.newAgentTracer({
        exclude: {
            modules: ["linker64"],
            syscalls: ["clock_gettime"]
        }
    }).start();
});

after npm compile
running frida -U -f com.android.contacts -l _agent.js --no-pause:

    / _  |   Frida 15.2.2 - 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 xx xxxx (id=xxxxx)
Spawned `com.android.contacts`. Resuming main thread!                   
[xx xxxx::com.android.contacts ]-> [INTERRUPTOR][STARTING] Tracing thread 9240 []
[STARTING TRACE] UID=0 Thread 9240
Deploying pthread_create hook
[libc.so] Hooking routine : 0x77222ef1a0 {"0x77222ef1a0":true}
------- [TID=9274][libutils.so][0x77222ef1a0] Thread routine start -------
[INTERRUPTOR][STARTING] Tracing thread 9274 []
[STARTING TRACE] UID=1 Thread 9274
Process crashed: Trace/BPT trap

***
*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
RROS Version: 'RROS-Q-8.6.5-20201226-starlte-Official'
Build fingerprint: 'samsung/starltexx/starlte:10/xxxxxxxxxxx:user/release-keys'
Revision: '26'
ABI: 'arm64'
Timestamp: 2022-08-05 23:21:56+0600
pid: 9240, tid: 9240, name: ndroid.contacts  >>> com.android.contacts <<<
uid: 10246
signal 6 (SIGABRT), code -1 (SI_QUEUE), fault addr --------
Abort message: 'Check failed: dex_pc < accessor.InsnsSizeInCodeUnits() (dex_pc=4294967295, accessor.InsnsSizeInCodeUnits()=1421) '
    x0  0000000000000000  x1  0000000000002418  x2  0000000000000006  x3  0000007fc6ddab50
    x4  0000007687fb6940  x5  0000007687fb6940  x6  0000007687fb6940  x7  0000007687fb6800
    x8  00000000000000f0  x9  000000771efe44a0  x10 0000000000000000  x11 0000000000000001
    x12 0000007687fb6300  x13 0000007687fb6440  x14 0000000000000001  x15 00000077234c5540
    x16 000000771f0b18c0  x17 000000771f08f310  x18 0000000000000000  x19 00000000000000ac
    x20 0000000000002418  x21 00000000000000b2  x22 0000000000002418  x23 00000000ffffffff
    x24 000000769e2d4104  x25 000000769e2d6104  x26 000000769e2b62e7  x27 0000007723178258
    x28 000000769e7f2000  x29 0000007fc6ddac00
    sp  0000007fc6ddab30  lr  000000771f042170  pc  000000771f0421a0

backtrace:
      #00 pc 00000000000821a0  /apex/com.android.runtime/lib64/bionic/libc.so!libc.so (offset 0x82000) (abort+176) (BuildId: a5aa1dd8572ed64645c321b17b43e24d)
      #01 pc 0000000000000108  <anonymous:7696080000>
***
[xx xxxx::com.android.contacts ]->

Thank you for using Frida!

If I'm gonna remove modules: ["linker64"], from the agent script will get Process crashed: Bad access due to invalid address error:

     ____
    / _  |   Frida 15.2.2 - 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 xx xxxx (id=xxxxx)
Spawned `com.android.contacts`. Resuming main thread!                   
[xx xxxx::com.android.contacts ]-> [INTERRUPTOR][STARTING] Tracing thread 9304 []
[STARTING TRACE] UID=0 Thread 9304
Deploying pthread_create hook
 [TID=9304] [/apex/com.android.runtime/lib64/bionic/libc.so +0x1614]   mprotect (   addr = 0x12c40000 ,  size = 0x40000 ,  prot = PROT_READ | PROT_WRITE  )    > 0 SUCCESS
Process crashed: Bad access due to invalid address

***
*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
RROS Version: 'RROS-Q-8.6.5-20201226-starlte-Official'
Build fingerprint: 'samsung/starltexx/starlte:10/xxxxxxxxxxxxxxx:user/release-keys'
Revision: '26'
ABI: 'arm64'
Timestamp: 2022-08-05 23:24:30+0600
pid: 9304, tid: 9304, name: ndroid.contacts  >>> com.android.contacts <<<
uid: 10246
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x120
Cause: null pointer dereference
    x0  0000000000000000  x1  000000769e7b4e4c  x2  00000076423f3060  x3  0000007fc6ddaaa0
    x4  00000076423f6d30  x5  0000007fc6ddaf78  x6  0000007fc6ddaf70  x7  0000000000000018
    x8  0000000000000000  x9  0000000000000000  x10 0000000000000072  x11 0000000000000001
    x12 0000000070ec61c8  x13 ffffffffffffffff  x14 0000000000000000  x15 000000769e723198
    x16 0000000000000001  x17 0000000000000000  x18 0000000000000000  x19 000000769e7b4e4c
    x20 0000000000000000  x21 0000000000000007  x22 0000000071bdcc10  x23 00000077237f9020
    x24 0000000000000000  x25 0000000071d3cb50  x26 0000000071d3cae8  x27 0000000016f400e0
    x28 000000772350ac00  x29 0000007fc6ddab20
    sp  0000007fc6dda970  lr  000000769e7b4e50  pc  0000007631a356c8

backtrace:
      #00 pc 00000000000096c8  <anonymous:7631a2c000>
      #01 pc 000000000058fe4c  /apex/com.android.runtime/lib64/libart.so!libart.so (offset 0x58f000) (_ZN3artL37JniMethodEndWithReferenceHandleResultEP8_jobjectjPNS_6ThreadE.llvm.15732748762076278778+68) (BuildId: 666654ef4cf00eb4a229a0a82fb8580b)
      #02 pc 000000000058fe4c  /apex/com.android.runtime/lib64/libart.so!libart.so (offset 0x58f000) (_ZN3artL37JniMethodEndWithReferenceHandleResultEP8_jobjectjPNS_6ThreadE.llvm.15732748762076278778+68) (BuildId: 666654ef4cf00eb4a229a0a82fb8580b)
      #03 pc 00000000000b61fc  /system/framework/arm64/boot.oat (art_jni_trampoline+140) (BuildId: a8ac55bddd29586f0b1ef039f0785f47489a899b)
      #04 pc 00000000000de208  /system/framework/arm64/boot.oat!boot.oat (offset 0xde000) (java.lang.ref.Reference.get+40) (BuildId: a8ac55bddd29586f0b1ef039f0785f47489a899b)
      #05 pc 00000000000db7e8  /system/framework/arm64/boot.oat!boot.oat (offset 0xdb000) (java.lang.ThreadLocal.get+152) (BuildId: a8ac55bddd29586f0b1ef039f0785f47489a899b)
      #06 pc 000000000075a7cc  /system/framework/arm64/boot-framework.oat!boot-framework.oat (offset 0x759000) (android.os.StrictMode.setBlockGuardPolicy+204) (BuildId: 70f26bc2948d2b8de567ee63d027da3521d905c0)
      #07 pc 000000000075962c  /system/framework/arm64/boot-framework.oat!boot-framework.oat (offset 0x759000) (android.os.StrictMode.initThreadDefaults+476) (BuildId: 70f26bc2948d2b8de567ee63d027da3521d905c0)
      #08 pc 00000000004bf3cc  /system/framework/arm64/boot-framework.oat!boot-framework.oat (offset 0x4bf000) (android.app.ActivityThread.handleBindApplication+2396) (BuildId: 70f26bc2948d2b8de567ee63d027da3521d905c0)
      #09 pc 0000000000136334  /apex/com.android.runtime/lib64/libart.so!libart.so (offset 0x135000) (art_quick_invoke_stub+548) (BuildId: 666654ef4cf00eb4a229a0a82fb8580b)
      #10 pc 00000000001450ac  /apex/com.android.runtime/lib64/libart.so!libart.so (offset 0x145000) (art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*)+244) (BuildId: 666654ef4cf00eb4a229a0a82fb8580b)
      #11 pc 00000000004b0390  /apex/com.android.runtime/lib64/libart.so!libart.so (offset 0x433000) (art::(anonymous namespace)::InvokeWithArgArray(art::ScopedObjectAccessAlreadyRunnable const&, art::ArtMethod*, art::(anonymous namespace)::ArgArray*, art::JValue*, char const*)+104) (BuildId: 666654ef4cf00eb4a229a0a82fb8580b)
      #12 pc 00000000004afff0  /apex/com.android.runtime/lib64/libart.so!libart.so (offset 0x433000) (art::InvokeWithVarArgs(art::ScopedObjectAccessAlreadyRunnable const&, _jobject*, _jmethodID*, std::__va_list)+408) (BuildId: 666654ef4cf00eb4a229a0a82fb8580b)
      #13 pc 00000000003a54cc  /apex/com.android.runtime/lib64/libart.so!libart.so (offset 0x385000) (art::JNI::CallNonvirtualVoidMethod(_JNIEnv*, _jobject*, _jclass*, _jmethodID*, ...)+692) (BuildId: 666654ef4cf00eb4a229a0a82fb8580b)
      #14 pc 0000000000769ff4  /data/local/tmp/re.frida.server/frida-agent-64.so!libfrida-agent.so (offset 0x769000)
      #15 pc 00000000007675bc  /data/local/tmp/re.frida.server/frida-agent-64.so!libfrida-agent.so (offset 0x767000)
***
[xx xxxx::com.android.contacts ]->

Thank you for using Frida!

with/without --no-pause have same result

'require' is not defined

demo examples\android\simple_strace.js
1、frida-compile simple_strace.js -o trace.js
2、frida -U -f pkg -l strace.js --no-paus
error:
ReferenceError: 'require' is not defined
at (/strace.js:1)

src:
var em_module = require('./android-arm64-strace.min.js').target.LinuxArm64();
Java.perform(() => {
em_module.newAgentTracer({
exclude: {
syscalls: ["clock_gettime"]
}
}).start();
});

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.