frida / frida-go

Frida Go bindings
https://frida.re/
ISC License
153 stars 19 forks source link

Can't resume portal device process #51

Open Redict opened 1 week ago

Redict commented 1 week ago

I have a custom solution built on top of the frida-go, consisting of two applications: a client and a server.

Client Application (Mobile):

  1. Runs on a mobile phone.
  2. Launches the process and connects it to a frida-portal.

Server Application (Portal):

  1. Acts as a central hub.
  2. Attaches a script to each newly connected process and attempts to interact with it.

Problem: The server cannot resume the process after it has been paused unless the client application terminates.

Steps to Reproduce:

Expected Behavior:

Actual Behavior:

Environment:

Logs

2024-10-05T10:53:44+03:00 ~ info ~ selfcontroller ~ ~/portal/portal.go:124 ~ node joined ~ {"connId": 2, "app": "app_process64", "pid": 1905}
2024-10-05T10:53:44+03:00 ~ info ~ ~/appctrl/appctrl.go:46 ~ attached to application ~ {"pid": 1905}
2024-10-05T10:53:44+03:00 ~ info ~ ~/appctrl/appctrl.go:52 ~ script readen from disk ~ {"size": 24665}
2024-10-05T10:53:44+03:00 ~ info ~ ~/appctrl/appctrl.go:61 ~ script created on remote ~ {"is_destroyed": false}
2024-10-05T10:53:44+03:00 ~ info ~ ~/appctrl/appctrl.go:63 ~ script ~ {"message": "{\"type\":\"log\",\"level\":\"info\",\"payload\":\"Script loaded\"}", "data": ""}
2024-10-05T10:53:44+03:00 ~ info ~ ~/appctrl/appctrl.go:76 ~ script loaded on remote ~ {"is_destroyed": false}
2024-10-05T10:53:44+03:00 ~ info ~ ~/appctrl/appctrl.go:87 ~ application resumed on remote
2024-10-05T10:53:54+03:00 ~ info ~ ~/appctrl/appctrl.go:66 ~ script destroyed!
2024-10-05T10:53:54+03:00 ~ info ~ selfcontroller ~ ~/portal/portal.go:140 ~ node disconnect ~ {"connId": 2, "app": "/system/bin/app_process64", "pid": 1905}
2024-10-05T10:53:54+03:00 ~ info ~ ~/appctrl/appctrl.go:69 ~ detached ~ {"reason": "process-terminated", "crash": ""}

Client code (simplified):

spawnOptions := frida.NewSpawnOptions()
pid, err := bc.device.Spawn(devctrl.AppName, spawnOptions)
if err != nil {
    utils.LogController.Error("failed to spawn application", zap.Error(err))
    return
}
utils.LogController.Info("running", zap.Any("pid", pid))
session, err := bc.device.Attach(pid, frida.NewSessionOptions(frida.RealmNative, 30000))
if err != nil {
    utils.LogController.Error("failed to attach to application", zap.Error(err))
    return
}
portalOptions := frida.NewPortalOptions()
portalOptions.SetToken(bc.env.PortalToken)
portal, err := session.JoinPortal(bc.env.PortalAddress, portalOptions)
if err != nil {
    utils.LogController.Error("failed to join portal", zap.Error(err))
    return
}
utils.LogController.Info("joined to portal", zap.Any("id", portal.ID()))

Server code (simplified):

attachOptions := frida.NewSessionOptions(frida.RealmNative, 0)
session, err := device.Attach(app.PID(), attachOptions)
if err != nil {
    return err
}
logger.Info("attached to application", zap.Any("pid", app.PID()))
scriptData, err := os.ReadFile(path.Join(env.DefaultPath, env.FilenameScript))
if err != nil {
    logger.Error("failed to read script data", zap.Error(err))
    return err
}
logger.Info("script readen from disk", zap.Any("size", len(scriptData)))
scriptOptions := frida.NewScriptOptions("main")
scriptOptions.SetRuntime(frida.ScriptRuntimeV8)
master.script, err = session.CreateScriptWithOptions(string(scriptData), scriptOptions)
if err != nil {
    logger.Error("failed to create script in application", zap.Error(err))
    return err
}
logger.Info("script created on remote", zap.Any("is_destroyed", master.script.IsDestroyed()))
master.script.On("message", func(message string, data []byte) {
    logger.Info("script", zap.String("message", message), zap.String("data", string(data)))
})
master.script.On("destroyed", func() {
    logger.Info("script destroyed!")
})
session.On("detached", func(reason frida.SessionDetachReason, crash *frida.Crash) {
    logger.Info("detached", zap.Any("reason", reason), zap.Any("crash", crash.Report()))
})
err = master.script.Load()
if err != nil {
    logger.Error("failed to run script in application", zap.Error(err))
    return err
}
logger.Info("script loaded on remote", zap.Any("is_destroyed", master.script.IsDestroyed()))
err = session.Resume()
if err != nil {
    logger.Error("failed to resume script in application", zap.Error(err))
    return err
}
logger.Info("application resumed on remote")
NSEcho commented 13 hours ago

Hi @Redict, I will get to this probably on Sunday as I was quite busy lately

dylanhitt commented 13 hours ago

@Redict you may want to give the latest frida-core a try?

I was experiencing a similar issue and has gone away since bumping to latest.