Program: 94067
Project: 94067
Buggy source:
static void initImageSave(final XC_LoadPackage.LoadPackageParam lpparam,final XModuleResources modRes){
  findAndHookMethod("String_Node_Str",lpparam.classLoader,"String_Node_Str",List.class,findClass("String_Node_Str",lpparam.classLoader),List.class,View.class,findClass("String_Node_Str",lpparam.classLoader),new XC_MethodHook(){
    @Override protected void beforeHookedMethod(    MethodHookParam param) throws Throwable {
      super.beforeHookedMethod(param);
      if (!Preferences.getBool(Prefs.CHAT_MEDIA_SAVE))       return;
      Logger.log("String_Node_Str",LogType.CHAT);
      Object chatMedia=param.args[1];
      String mKey=(String)getObjectField(chatMedia,"String_Node_Str");
      if (mKey == null) {
        Logger.log("String_Node_Str",LogType.CHAT);
        return;
      }
      Logger.log("String_Node_Str" + mKey,LogType.CHAT);
      if (!chatMediaMap.containsKey(mKey))       chatMediaMap.put(mKey,chatMedia);
 else       Logger.log("String_Node_Str",LogType.CHAT);
    }
  }
);
  findAndHookMethod("String_Node_Str",lpparam.classLoader,"String_Node_Str",new XC_MethodHook(){
    @Override protected void beforeHookedMethod(    MethodHookParam param) throws Throwable {
      super.beforeHookedMethod(param);
      if (!Preferences.getBool(Prefs.CHAT_MEDIA_SAVE))       return;
      Logger.log("String_Node_Str",LogType.CHAT);
      Object godPacket=getObjectField(param.thisObject,"String_Node_Str");
      Map<String,Object> map=(Map<String,Object>)getObjectField(godPacket,"String_Node_Str");
      String mKey=(String)map.get("String_Node_Str");
      String mMediaUrl=(String)map.get("String_Node_Str");
      String[] arrSplitUrl=mMediaUrl.split("String_Node_Str");
      if (arrSplitUrl.length <= 0) {
        Logger.log("String_Node_Str",LogType.CHAT);
        return;
      }
      String splitUrl=arrSplitUrl[1];
      Logger.log(String.format("String_Node_Str",mKey,splitUrl),LogType.CHAT);
      Object chatMedia=chatMediaMap.get(mKey);
      if (chatMedia == null) {
        Logger.log("String_Node_Str",LogType.CHAT);
        return;
      }
      chatMediaMap.remove(mKey);
      chatMediaMap.put(splitUrl,chatMedia);
      Logger.log("String_Node_Str" + splitUrl,LogType.CHAT);
    }
  }
);
  findAndHookMethod("String_Node_Str",lpparam.classLoader,"String_Node_Str",MotionEvent.class,new XC_MethodHook(){
    private GestureDetector gestureDetector;
    @Override protected void beforeHookedMethod(    MethodHookParam param) throws Throwable {
      super.beforeHookedMethod(param);
      if (!Preferences.getBool(Prefs.CHAT_MEDIA_SAVE))       return;
      MotionEvent event=(MotionEvent)param.args[0];
      ViewGroup viewGroup=(ViewGroup)param.thisObject;
      if (gestureDetector == null) {
        gestureDetector=new GestureDetector(new MediaGestureListener((ViewGroup)param.thisObject){
          @Override public void onLongPress(          MotionEvent e){
            Logger.log("String_Node_Str",LogType.CHAT);
            try {
              int childCount=this.mediaLayout.getChildCount();
              if (childCount > 0) {
                FrameLayout videoLayout=(FrameLayout)this.mediaLayout.getChildAt(0);
                for (int i=0; i < videoLayout.getChildCount(); i++) {
                  View view=videoLayout.getChildAt(i);
                  if (view.getId() != +2131690096)                   return;
                  Logger.log("String_Node_Str",LogType.CHAT);
                  Uri videoUri=(Uri)getObjectField(view,"String_Node_Str");
                  String splitUrl;
                  if (videoUri == null) {
                    Logger.log("String_Node_Str",LogType.CHAT);
                    splitUrl=(String)getAdditionalInstanceField(view,"String_Node_Str");
                    if (splitUrl == null) {
                      Logger.log("String_Node_Str",LogType.CHAT);
                      return;
                    }
                  }
 else {
                    String strVideoUrl=videoUri.getPath();
                    String[] arrSplitUrl=strVideoUrl.split("String_Node_Str");
                    if (arrSplitUrl.length <= 0) {
                      Logger.log("String_Node_Str",LogType.CHAT);
                      return;
                    }
                    splitUrl=arrSplitUrl[1];
                  }
                  Logger.log("String_Node_Str" + splitUrl);
                  Object chatMedia=chatMediaMap.get(splitUrl);
                  if (chatMedia == null) {
                    Logger.log("String_Node_Str" + splitUrl,LogType.CHAT);
                    return;
                  }
                  Logger.log("String_Node_Str",LogType.CHAT);
                  Long timestamp=(Long)callMethod(chatMedia,"String_Node_Str");
                  Logger.log("String_Node_Str" + timestamp,LogType.CHAT);
                  String sender=(String)getObjectField(chatMedia,"String_Node_Str");
                  Logger.log("String_Node_Str" + sender,LogType.CHAT);
                  String formattedTimestamp=savingDateFormat.format(timestamp);
                  String mId=(String)getObjectField(chatMedia,"String_Node_Str");
                  String filename=String.format("String_Node_Str",sender,formattedTimestamp,mId.hashCode() % 999999);
                  Logger.log("String_Node_Str" + obfus(sender) + "String_Node_Str"+ formattedTimestamp,LogType.CHAT);
                  FileInputStream video=new FileInputStream(videoUri.getPath());
                  Saving.SaveResponse response=Saving.saveSnap(Saving.SnapType.CHAT,Saving.MediaType.VIDEO,view.getContext(),null,video,filename,sender);
                  if (response == Saving.SaveResponse.SUCCESS) {
                    Logger.log("String_Node_Str",LogType.CHAT);
                    Saving.createStatefulToast("String_Node_Str",NotificationUtils.ToastType.GOOD);
                  }
 else                   if (response == Saving.SaveResponse.EXISTING) {
                    Logger.log("String_Node_Str",LogType.CHAT);
                    Saving.createStatefulToast("String_Node_Str",NotificationUtils.ToastType.WARNING);
                  }
 else                   if (response == Saving.SaveResponse.FAILED) {
                    Logger.log("String_Node_Str",LogType.CHAT);
                    Saving.createStatefulToast("String_Node_Str",NotificationUtils.ToastType.BAD);
                  }
 else {
                    Logger.log("String_Node_Str",LogType.CHAT);
                    Saving.createStatefulToast("String_Node_Str",NotificationUtils.ToastType.WARNING);
                  }
                }
              }
            }
 catch (            Exception ex) {
              Logger.log("String_Node_Str",ex,LogType.CHAT.setForced());
              Saving.createStatefulToast("String_Node_Str",ToastType.BAD);
            }
          }
        }
);
      }
      if (gestureDetector.onTouchEvent(event))       return;
      if (event.getAction() != MotionEvent.ACTION_UP)       param.setResult(true);
    }
  }
);
  findAndHookMethod("String_Node_Str",lpparam.classLoader,"String_Node_Str",new XC_MethodHook(){
    @Override protected void beforeHookedMethod(    MethodHookParam param) throws Throwable {
      super.beforeHookedMethod(param);
      Logger.log("String_Node_Str",LogType.CHAT);
      Uri videoUri=(Uri)getObjectField(param.thisObject,"String_Node_Str");
      if (videoUri == null) {
        Logger.log("String_Node_Str",LogType.CHAT);
        return;
      }
      String strVideoUrl=videoUri.getPath();
      String[] arrSplitUrl=strVideoUrl.split("String_Node_Str");
      if (arrSplitUrl.length <= 0) {
        Logger.log("String_Node_Str",LogType.CHAT);
        return;
      }
      String splitUrl=arrSplitUrl[1];
      setAdditionalInstanceField(param.thisObject,"String_Node_Str",splitUrl);
      Logger.log("String_Node_Str",LogType.CHAT);
    }
  }
);
  findAndHookConstructor("String_Node_Str",lpparam.classLoader,findClass("String_Node_Str",lpparam.classLoader),findClass("String_Node_Str",lpparam.classLoader),Context.class,findClass("String_Node_Str",lpparam.classLoader),findClass("String_Node_Str",lpparam.classLoader),findClass("String_Node_Str",lpparam.classLoader),new XC_MethodHook(){
    @Override protected void afterHookedMethod(    final MethodHookParam param) throws Throwable {
      super.afterHookedMethod(param);
      if (!Preferences.getBool(Prefs.CHAT_MEDIA_SAVE))       return;
      final ImageView imageView=(ImageView)getObjectField(param.thisObject,"String_Node_Str");
      imageView.setOnLongClickListener(new View.OnLongClickListener(){
        @Override public boolean onLongClick(        View v){
          try {
            Logger.log("String_Node_Str",LogType.CHAT);
            Bitmap chatImage=((BitmapDrawable)imageView.getDrawable()).getBitmap();
            if (chatImage == null) {
              Logger.log("String_Node_Str",LogType.CHAT);
              return true;
            }
            final Object godPacket=getObjectField(param.thisObject,"String_Node_Str");
            final Map<String,Object> map=(Map<String,Object>)getObjectField(godPacket,"String_Node_Str");
            if (map == null) {
              Logger.log("String_Node_Str",LogType.CHAT);
              return true;
            }
            final String mKey=(String)map.get("String_Node_Str");
            if (mKey == null) {
              Logger.log("String_Node_Str",LogType.CHAT);
              return true;
            }
            Logger.log("String_Node_Str" + mKey,LogType.CHAT);
            final Object chatMedia=chatMediaMap.get(mKey);
            if (chatMedia == null) {
              Logger.log("String_Node_Str",LogType.CHAT);
              return true;
            }
            Long timestamp=(Long)callMethod(chatMedia,"String_Node_Str");
            Logger.log("String_Node_Str" + timestamp,LogType.CHAT);
            String sender=(String)getObjectField(chatMedia,"String_Node_Str");
            Logger.log("String_Node_Str" + obfus(sender),LogType.CHAT);
            String formattedTimestamp=savingDateFormat.format(timestamp);
            String mId=(String)getObjectField(chatMedia,"String_Node_Str");
            String filename=String.format("String_Node_Str",sender,formattedTimestamp,mId.hashCode() % 999999);
            Logger.log("String_Node_Str" + obfus(sender) + "String_Node_Str"+ formattedTimestamp+ "String_Node_Str"+ (mId.hashCode() % 999999),LogType.CHAT);
            Saving.SaveResponse response=Saving.saveSnap(Saving.SnapType.CHAT,Saving.MediaType.IMAGE,imageView.getContext(),chatImage,null,filename,sender);
            if (response == Saving.SaveResponse.SUCCESS) {
              Logger.log("String_Node_Str",LogType.CHAT);
              Saving.createStatefulToast("String_Node_Str",NotificationUtils.ToastType.GOOD);
            }
 else             if (response == Saving.SaveResponse.EXISTING) {
              Logger.log("String_Node_Str",LogType.CHAT);
              Saving.createStatefulToast("String_Node_Str",NotificationUtils.ToastType.WARNING);
            }
 else             if (response == Saving.SaveResponse.FAILED) {
              Logger.log("String_Node_Str",LogType.CHAT);
              Saving.createStatefulToast("String_Node_Str",NotificationUtils.ToastType.BAD);
            }
 else {
              Logger.log("String_Node_Str",LogType.CHAT);
              Saving.createStatefulToast("String_Node_Str",NotificationUtils.ToastType.WARNING);
            }
            return false;
          }
 catch (          Exception e) {
            Logger.log("String_Node_Str",e,LogType.CHAT.setForced());
            Saving.createStatefulToast("String_Node_Str",NotificationUtils.ToastType.BAD);
            return true;
          }
        }
      }
);
    }
  }
);
}

Fixed version (ground truth):
static void initImageSave(final XC_LoadPackage.LoadPackageParam lpparam,final XModuleResources modRes){
  findAndHookMethod("String_Node_Str",lpparam.classLoader,"String_Node_Str",List.class,findClass("String_Node_Str",lpparam.classLoader),List.class,View.class,findClass("String_Node_Str",lpparam.classLoader),new XC_MethodHook(){
    @Override protected void beforeHookedMethod(    MethodHookParam param) throws Throwable {
      super.beforeHookedMethod(param);
      if (!Preferences.getBool(Prefs.CHAT_MEDIA_SAVE))       return;
      Logger.log("String_Node_Str",LogType.CHAT);
      Object chatMedia=param.args[1];
      String mKey=(String)getObjectField(chatMedia,"String_Node_Str");
      if (mKey == null) {
        Logger.log("String_Node_Str",LogType.CHAT);
        return;
      }
      Logger.log("String_Node_Str" + mKey,LogType.CHAT);
      if (!chatMediaMap.containsKey(mKey))       chatMediaMap.put(mKey,chatMedia);
 else       Logger.log("String_Node_Str",LogType.CHAT);
    }
  }
);
  findAndHookMethod("String_Node_Str",lpparam.classLoader,"String_Node_Str",new XC_MethodHook(){
    @Override protected void beforeHookedMethod(    MethodHookParam param) throws Throwable {
      super.beforeHookedMethod(param);
      if (!Preferences.getBool(Prefs.CHAT_MEDIA_SAVE))       return;
      Logger.log("String_Node_Str",LogType.CHAT);
      Object godPacket=getObjectField(param.thisObject,"String_Node_Str");
      Map<String,Object> map=(Map<String,Object>)getObjectField(godPacket,"String_Node_Str");
      String mKey=(String)map.get("String_Node_Str");
      String mMediaUrl=(String)map.get("String_Node_Str");
      String[] arrSplitUrl=mMediaUrl.split("String_Node_Str");
      if (arrSplitUrl.length <= 1) {
        Logger.log("String_Node_Str",LogType.CHAT);
        return;
      }
      String splitUrl=arrSplitUrl[1];
      Logger.log(String.format("String_Node_Str",mKey,splitUrl),LogType.CHAT);
      Object chatMedia=chatMediaMap.get(mKey);
      if (chatMedia == null) {
        Logger.log("String_Node_Str",LogType.CHAT);
        return;
      }
      chatMediaMap.remove(mKey);
      chatMediaMap.put(splitUrl,chatMedia);
      Logger.log("String_Node_Str" + splitUrl,LogType.CHAT);
    }
  }
);
  findAndHookMethod("String_Node_Str",lpparam.classLoader,"String_Node_Str",MotionEvent.class,new XC_MethodHook(){
    private GestureDetector gestureDetector;
    @Override protected void beforeHookedMethod(    MethodHookParam param) throws Throwable {
      super.beforeHookedMethod(param);
      if (!Preferences.getBool(Prefs.CHAT_MEDIA_SAVE))       return;
      MotionEvent event=(MotionEvent)param.args[0];
      ViewGroup viewGroup=(ViewGroup)param.thisObject;
      if (gestureDetector == null) {
        gestureDetector=new GestureDetector(new MediaGestureListener((ViewGroup)param.thisObject){
          @Override public void onLongPress(          MotionEvent e){
            Logger.log("String_Node_Str",LogType.CHAT);
            try {
              int childCount=this.mediaLayout.getChildCount();
              if (childCount > 0) {
                FrameLayout videoLayout=(FrameLayout)this.mediaLayout.getChildAt(0);
                for (int i=0; i < videoLayout.getChildCount(); i++) {
                  View view=videoLayout.getChildAt(i);
                  if (view.getId() != +2131690096)                   return;
                  Logger.log("String_Node_Str",LogType.CHAT);
                  Uri videoUri=(Uri)getObjectField(view,"String_Node_Str");
                  String splitUrl;
                  if (videoUri == null) {
                    Logger.log("String_Node_Str",LogType.CHAT);
                    splitUrl=(String)getAdditionalInstanceField(view,"String_Node_Str");
                    if (splitUrl == null) {
                      Logger.log("String_Node_Str",LogType.CHAT);
                      return;
                    }
                  }
 else {
                    String strVideoUrl=videoUri.getPath();
                    String[] arrSplitUrl=strVideoUrl.split("String_Node_Str");
                    if (arrSplitUrl.length <= 0) {
                      Logger.log("String_Node_Str",LogType.CHAT);
                      return;
                    }
                    splitUrl=arrSplitUrl[1];
                  }
                  Logger.log("String_Node_Str" + splitUrl);
                  Object chatMedia=chatMediaMap.get(splitUrl);
                  if (chatMedia == null) {
                    Logger.log("String_Node_Str" + splitUrl,LogType.CHAT);
                    return;
                  }
                  Logger.log("String_Node_Str",LogType.CHAT);
                  Long timestamp=(Long)callMethod(chatMedia,"String_Node_Str");
                  Logger.log("String_Node_Str" + timestamp,LogType.CHAT);
                  String sender=(String)getObjectField(chatMedia,"String_Node_Str");
                  Logger.log("String_Node_Str" + sender,LogType.CHAT);
                  String formattedTimestamp=savingDateFormat.format(timestamp);
                  String mId=(String)getObjectField(chatMedia,"String_Node_Str");
                  String filename=String.format("String_Node_Str",sender,formattedTimestamp,mId.hashCode() % 999999);
                  Logger.log("String_Node_Str" + obfus(sender) + "String_Node_Str"+ formattedTimestamp,LogType.CHAT);
                  FileInputStream video=new FileInputStream(videoUri.getPath());
                  Saving.SaveResponse response=Saving.saveSnap(Saving.SnapType.CHAT,Saving.MediaType.VIDEO,view.getContext(),null,video,filename,sender);
                  if (response == Saving.SaveResponse.SUCCESS) {
                    Logger.log("String_Node_Str",LogType.CHAT);
                    Saving.createStatefulToast("String_Node_Str",NotificationUtils.ToastType.GOOD);
                  }
 else                   if (response == Saving.SaveResponse.EXISTING) {
                    Logger.log("String_Node_Str",LogType.CHAT);
                    Saving.createStatefulToast("String_Node_Str",NotificationUtils.ToastType.WARNING);
                  }
 else                   if (response == Saving.SaveResponse.FAILED) {
                    Logger.log("String_Node_Str",LogType.CHAT);
                    Saving.createStatefulToast("String_Node_Str",NotificationUtils.ToastType.BAD);
                  }
 else {
                    Logger.log("String_Node_Str",LogType.CHAT);
                    Saving.createStatefulToast("String_Node_Str",NotificationUtils.ToastType.WARNING);
                  }
                }
              }
            }
 catch (            Exception ex) {
              Logger.log("String_Node_Str",ex,LogType.CHAT.setForced());
              Saving.createStatefulToast("String_Node_Str",ToastType.BAD);
            }
          }
        }
);
      }
      if (gestureDetector.onTouchEvent(event))       return;
      if (event.getAction() != MotionEvent.ACTION_UP)       param.setResult(true);
    }
  }
);
  findAndHookMethod("String_Node_Str",lpparam.classLoader,"String_Node_Str",new XC_MethodHook(){
    @Override protected void beforeHookedMethod(    MethodHookParam param) throws Throwable {
      super.beforeHookedMethod(param);
      Logger.log("String_Node_Str",LogType.CHAT);
      Uri videoUri=(Uri)getObjectField(param.thisObject,"String_Node_Str");
      if (videoUri == null) {
        Logger.log("String_Node_Str",LogType.CHAT);
        return;
      }
      String strVideoUrl=videoUri.getPath();
      String[] arrSplitUrl=strVideoUrl.split("String_Node_Str");
      if (arrSplitUrl.length <= 1) {
        Logger.log("String_Node_Str",LogType.CHAT);
        return;
      }
      String splitUrl=arrSplitUrl[1];
      setAdditionalInstanceField(param.thisObject,"String_Node_Str",splitUrl);
      Logger.log("String_Node_Str",LogType.CHAT);
    }
  }
);
  findAndHookConstructor("String_Node_Str",lpparam.classLoader,findClass("String_Node_Str",lpparam.classLoader),findClass("String_Node_Str",lpparam.classLoader),Context.class,findClass("String_Node_Str",lpparam.classLoader),findClass("String_Node_Str",lpparam.classLoader),findClass("String_Node_Str",lpparam.classLoader),new XC_MethodHook(){
    @Override protected void afterHookedMethod(    final MethodHookParam param) throws Throwable {
      super.afterHookedMethod(param);
      if (!Preferences.getBool(Prefs.CHAT_MEDIA_SAVE))       return;
      final ImageView imageView=(ImageView)getObjectField(param.thisObject,"String_Node_Str");
      imageView.setOnLongClickListener(new View.OnLongClickListener(){
        @Override public boolean onLongClick(        View v){
          try {
            Logger.log("String_Node_Str",LogType.CHAT);
            Bitmap chatImage=((BitmapDrawable)imageView.getDrawable()).getBitmap();
            if (chatImage == null) {
              Logger.log("String_Node_Str",LogType.CHAT);
              return true;
            }
            final Object godPacket=getObjectField(param.thisObject,"String_Node_Str");
            final Map<String,Object> map=(Map<String,Object>)getObjectField(godPacket,"String_Node_Str");
            if (map == null) {
              Logger.log("String_Node_Str",LogType.CHAT);
              return true;
            }
            final String mKey=(String)map.get("String_Node_Str");
            if (mKey == null) {
              Logger.log("String_Node_Str",LogType.CHAT);
              return true;
            }
            Logger.log("String_Node_Str" + mKey,LogType.CHAT);
            final Object chatMedia=chatMediaMap.get(mKey);
            if (chatMedia == null) {
              Logger.log("String_Node_Str",LogType.CHAT);
              return true;
            }
            Long timestamp=(Long)callMethod(chatMedia,"String_Node_Str");
            Logger.log("String_Node_Str" + timestamp,LogType.CHAT);
            String sender=(String)getObjectField(chatMedia,"String_Node_Str");
            Logger.log("String_Node_Str" + obfus(sender),LogType.CHAT);
            String formattedTimestamp=savingDateFormat.format(timestamp);
            String mId=(String)getObjectField(chatMedia,"String_Node_Str");
            String filename=String.format("String_Node_Str",sender,formattedTimestamp,mId.hashCode() % 999999);
            Logger.log("String_Node_Str" + obfus(sender) + "String_Node_Str"+ formattedTimestamp+ "String_Node_Str"+ (mId.hashCode() % 999999),LogType.CHAT);
            Saving.SaveResponse response=Saving.saveSnap(Saving.SnapType.CHAT,Saving.MediaType.IMAGE,imageView.getContext(),chatImage,null,filename,sender);
            if (response == Saving.SaveResponse.SUCCESS) {
              Logger.log("String_Node_Str",LogType.CHAT);
              Saving.createStatefulToast("String_Node_Str",NotificationUtils.ToastType.GOOD);
            }
 else             if (response == Saving.SaveResponse.EXISTING) {
              Logger.log("String_Node_Str",LogType.CHAT);
              Saving.createStatefulToast("String_Node_Str",NotificationUtils.ToastType.WARNING);
            }
 else             if (response == Saving.SaveResponse.FAILED) {
              Logger.log("String_Node_Str",LogType.CHAT);
              Saving.createStatefulToast("String_Node_Str",NotificationUtils.ToastType.BAD);
            }
 else {
              Logger.log("String_Node_Str",LogType.CHAT);
              Saving.createStatefulToast("String_Node_Str",NotificationUtils.ToastType.WARNING);
            }
            return false;
          }
 catch (          Exception e) {
            Logger.log("String_Node_Str",e,LogType.CHAT.setForced());
            Saving.createStatefulToast("String_Node_Str",NotificationUtils.ToastType.BAD);
            return true;
          }
        }
      }
);
    }
  }
);
}