Open jackie575 opened 9 months ago
Hey, can you paste the code that caused the error
Hey, can you paste the code that caused the error
Thanks For Your Reply!
Here is the code :
type FridaClient struct {
apiHooker *fridaApiHooker
//
refreshChan *chan uint32
// Client Version,
version * atomic.Uint32
// Frida Resource is ok?
OK bool
}
type fridaApiHooker struct {
deviceManager *frida.DeviceManager
device *frida.Device
session *frida.Session
script *frida.Script
}
// Close close the resource held by the frida client singleton
func (hooker fridaApiHooker) close() {
hooker.script.Clean()
hooker.session.Clean()
hooker.device.Clean()
hooker.deviceManager.Clean()
}
// newApiHooker make new frida Resource
func newApiHooker() *fridaApiHooker {
jsScript := readJsScript()
deviceManager := frida.NewDeviceManager()
devices, err := deviceManager.EnumerateDevices()
if err != nil {
panic("Device Error!")
}
for _, d := range devices {
log.Printf("[*] Found device with id:%v", d.ID())
}
device, err := deviceManager.USBDevice()
if err != nil {
log.Printf("Could not get usb device: %v", err)
os.Exit(1)
}
log.Printf("[*] Attaching to `App`")
session, err := device.Attach(processName, nil)
if err != nil {
log.Printf("New Session Fail!err:%v", err)
os.Exit(1)
}
fridaScript, err := session.CreateScript(jsScript)
if err != nil {
log.Printf("New Frida Script Fail! err:%v", err)
os.Exit(1)
}
if err := fridaScript.Load(); err != nil {
log.Printf("Load Frida Script Fail!err:%v", err)
os.Exit(1)
}
return &fridaApiHooker{
deviceManager: deviceManager,
device: device,
session: session,
script: fridaScript,
}
}
func (client * FridaClient) CallFrida(param *CallFridaParam) (*rpc.CallResult, error) {
// for loop 3 times
for i := 0; i < 3; i++ {
// every iteration , call the func , if err is TimeOutError,close
// the resource, reopen it
result, err := client.doFridaCallInner(param)
if err != nil {
if errors.Is(err, timeoutError) {
// Timeout Error,get Client Version
ver := client.version.Load()
*client.refreshChan <- ver
// wait for the client version greater than current,and 'ok'
// statuc switch to 'true'
for !(client.version.Load() > ver && client.OK) {
// wait for reloader to reload resource
time.Sleep(1 * time.Second)
}
continue
} else {
// other error than TimeOut
return nil, err
}
} else {
// call frida success ,just return it
return result, nil
}
}
// for loop end ,can't get result ,return err
return nil, timeoutError
}
func (client *FridaClient) doFridaCallInner(param *FridaCallParam) (*rpc.FridaResult, error) {
// make chan to recv result
ch := make(chan FridaResult, 1)
go func() {
defer close(ch)
resultMap := client.apiHooker.script.ExportsCall("JSFuncName",
//
params
)
ch <- FridaResult{resultMap, nil}
}()
// 4. 当前协程等待结果
select {
case <-time.After(RpcTimeout * time.Second):
{
//
return nil, timeoutError
}
case result := <-ch:
{
return &result,nil
}
}
}
// GetFridaClient make FridaClient Singleton
func GetFridaClient() *FridaClient {
clientInitLock.Do(func() {
log.Printf("init Frida client! ")
apiHooker := newApiHooker()
ch := make(chan uint32, 1)
ver := atomic.Uint32{}
// incr to version 1
ver.Add(1)
clientSingleton = &FridaClient{
apiHooker: apiHooker,
// version init to 1
version: &ver,
// size 1 channel
refreshChan: &ch,
//
OK: true,
}
// 7. launch a new coroutine , do for refresh Resource
go func() {
for {
// wait for channel recv
v := <-*clientSingleton.refreshChan
if v == clientSingleton.version.Load() {
// version equals ,do the resource refresh actions
casSuccess := clientSingleton.version.CompareAndSwap(v, v+1)
if casSuccess {
go func() {
log.Printf("resource clean up")
// when cas success ,refresh resource
clientSingleton.OK = false
defer func() { clientSingleton.OK = true }()
_ = clientSingleton.apiHooker.close()
// make new hooker ,update the prop of singleton
clientSingleton.apiHooker = newApiHooker()
}()
}
} else {
// Version different,Just return
log.Printf("", v, clientSingleton.version)
}
}
}()
})
return clientSingleton
}
HI ,I encounter a problem when many concurrent goroutine execute
Script.ExportsCall
;Here is The Env And Error Info===========
Any Other Info ,when the app call
Script.ExportsCall
Timeout, i think it is just broken Session,so i close the resource , reopen another DeviceManager 、Device、Session and so on; Here is the codeCan anyone help me to solve it? Many Thanks!