Can't resume portal device process
Opened this issue · 3 comments
I have a custom solution built on top of the frida-go, consisting of two applications: a client and a server.
Client Application (Mobile):
- Runs on a mobile phone.
- Launches the process and connects it to a frida-portal.
Server Application (Portal):
- Acts as a central hub.
- 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:
- Launch the client application on the mobile device and connect it to the Frida-portal.
- Observe the server successfully attaching to the process, loading the script.
- Attempt to resume the process again through the server.
- The process does not resume, process terminates.
Expected Behavior:
- The server should be able to resume the process without requiring the client application to terminate.
Actual Behavior:
- The server can only resume the process after the client application terminates.
Environment:
- Client: Samsung SM-A256E
- Server: Linux 5.15.153.1-microsoft-standard-WSL2 # 1 SMP Fri Mar 29 23:14:13 UTC 2024 x86_64 x86_64 x86_64 GNU/Linux
- Frida Version: frida-go 0.11.0, frida-core 16.4.10, 16.5.2 (tried both)
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")
@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.
@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.
I attempted that approach, but the results were identical. I have temporarily adopted gRPC to develop a functional product, though it's somewhat unconventional.