Repository

v-frida

This is the initial support of V for Frida.

V is a go-ish programming language that compiles to C and JS, this makes it ideal to target Frida, so it's possible to write host and target code using the same language.

The versatility of V and Frida, allow to write host and agent code in both C or Javascript. Making possible to reuse your nodejs host or agent scripts, or use CModule in the agent without changing a line in your V host or agent code.

Status

This is the list of checkbox to mark over time

  • Spawn local apps
  • Attach local/usb by pid
  • Trace methods (onEnter/onLeave)
  • Change return value onLeave
  • Enumerate modules, symbols and exports
  • Attach via USB by appname
  • Change argument values onEnter
  • Enumerate processes

Example

This is a simplified example usage for the host and agent side in pure V

Host

import frida.host
import os

fn load_agent() string {
    os.system('v -o agent.js agent.v')
    return os.read_file('agent.js')?
}

fn watchdog() ? {
    time.sleep(10 * 100000)
}

fn main() {
    dm := host.new_device_manager()
    device := dm.get_device_by_type(.local)?
    pid := device.spawn('/usr/local/bin/r2', {})?
    eprintln('ls: pid $pid')

    session := device.attach(pid)?
    session.on_detached(host.SessionDetachCallback(on_detached), voidptr(0))

    code := load_agent()
    script := session.create_script(code, {
        name: 'v-frida'
        on_message: host.ScriptMessageCallback(on_message)
        user_data: 0
    })?

    script.load()?
    fill := go watchdog(fs)
    fill.wait() or { eprintln('Oops: $err') }
    script.unload()?
    device.kill(pid)
}

Agent:

import frida.agent

fn on_message(mut stanza agent.Stanza, mut data agent.Data) {
    eprintln('message received! ${stanza.payload}')
    agent.recv(on_message)
}

fn main() {
    println('Hello world')
    agent.recv(on_message)
}

Show time

$ v -o agent.js agent.v
$ v run main.v
ls: pid 66485
message received: {"type":"log","level":"info","payload":"Hello world"}
message received: {"type":"log","level":"info","payload":"frida message received"}
message received: {"type":"log","level":"info","payload":"frida message received"}
message received: {"type":"log","level":"info","payload":"frida message received"}
...
V panic: The connection is closed
$

Running main demo

$ make
v -g main.v
./main
[>] frida: device-manager
[>] v: target
[>] frida: spawning
ls: pid 15709
[>] frida: loading script
[>] v: agent
loading
[main.v < agent.v]: Hello from the Agent side
[main.v < agent.v]: Symbol to hook found main__State_pull
[main.v < agent.v]: Stuff hooked
loaded
Count 666
Count 666
[main.v < agent.v]: pull method pwned
Count 666
[main.v < agent.v]: replace return value 666
Count 666
[main.v < agent.v]: pull method pwned
Count 666
[main.v < agent.v]: replace return value 666
Count 666
[main.v < agent.v]: pull method pwned
Count 666
Count 666
[main.v < agent.v]: replace return value 666
Count 666
[main.v < agent.v]: pull method pwned
Count 666
[main.v < agent.v]: replace return value 666
[main.v < agent.v]: pull method pwned
[main.v < agent.v]: replace return value 666
[main.v < agent.v]: pull method pwned
[>] frida: unloading the scene
unloaded
detached

About

0
65
1 year ago

Author

trufae