Open jackie575 opened 11 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!