bool is_clinit_invoked_method_benign()

in libredex/MethodUtil.cpp [179:479]


bool is_clinit_invoked_method_benign(const DexMethodRef* method_ref) {
  const auto& type_name = method_ref->get_class()->str();
  if (strcmp(type_name.c_str(), "Lcom/redex/OutlinedStringBuilders;") == 0) {
    return true;
  }

  const auto& name = method_ref->get_name()->str();
  if (strcmp(name.c_str(), "clone") == 0 ||
      strcmp(name.c_str(), "concat") == 0 ||
      strcmp(name.c_str(), "append") == 0) {
    return true;
  }

  static const std::unordered_set<std::string> methods = {
      // clang-format off
      "Landroid/content/Context;.getApplicationContext:()Landroid/content/Context;",
      "Landroid/content/Context;.getApplicationInfo:()Landroid/content/pm/ApplicationInfo;",
      "Landroid/content/Context;.getCacheDir:()Ljava/io/File;",
      "Landroid/content/Context;.getPackageName:()Ljava/lang/String;",
      "Landroid/content/ContextWrapper;.getApplicationContext:()Landroid/content/Context;",
      "Landroid/graphics/Color;.rgb:(III)I",
      "Landroid/graphics/Path;.<init>:()V",
      "Landroid/graphics/PointF;.<init>:(FF)V",
      "Landroid/graphics/Rect;.<init>:()V",
      "Landroid/net/Uri$Builder;.appendPath:(Ljava/lang/String;)Landroid/net/Uri$Builder;",
      "Landroid/net/Uri$Builder;.build:()Landroid/net/Uri;",
      "Landroid/net/Uri;.buildUpon:()Landroid/net/Uri$Builder;",
      "Landroid/net/Uri;.parse:(Ljava/lang/String;)Landroid/net/Uri;",
      "Landroid/os/Handler;.<init>:(Landroid/os/Looper;)V",
      "Landroid/os/Looper;.getMainLooper:()Landroid/os/Looper;",
      "Landroid/os/Process;.is64Bit:()Z",
      "Landroid/os/Trace;.beginSection:(Ljava/lang/String;)V",
      "Landroid/os/Trace;.endSection:()V",
      "Landroid/os/Process;.myPid:()I",
      "Landroid/os/Process;.myUid:()I",
      "Landroid/text/TextUtils;.isEmpty:(Ljava/lang/CharSequence;)Z",
      "Landroid/text/format/Time;.<init>:()V",
      "Landroid/util/Log;.e:(Ljava/lang/String;Ljava/lang/String;)I",
      "Landroid/util/Log;.isLoggable:(Ljava/lang/String;I)Z",
      "Landroid/util/Log;.w:(Ljava/lang/String;Ljava/lang/String;)I",
      "Landroid/util/SparseArray;.<init>:()V",
      "Landroid/util/SparseArray;.<init>:(I)V",
      "Landroid/util/SparseArray;.put:(ILjava/lang/Object;)V",
      "Ljava/io/BufferedReader;.<init>:(Ljava/io/Reader;)V",
      "Ljava/io/ByteArrayOutputStream;.<init>:()V",
      "Ljava/io/ByteArrayOutputStream;.toByteArray:()[B",
      "Ljava/io/File;.equals:(Ljava/lang/Object;)Z",
      "Ljava/io/File;.getAbsolutePath:()Ljava/lang/String;",
      "Ljava/io/File;.getCanonicalPath:()Ljava/lang/String;",
      "Ljava/io/File;.getParentFile:()Ljava/io/File;",
      "Ljava/io/OutputStream;.<init>:()V",
      "Ljava/io/OutputStream;.write:([B)V",
      "Ljava/io/PrintStream;.println:(Ljava/lang/String;)V",
      "Ljava/io/PrintWriter;.<init>:(Ljava/io/Writer;)V",
      "Ljava/io/PrintWriter;.close:()V",
      "Ljava/io/PrintWriter;.println:()V",
      "Ljava/io/Writer;.<init>:()V",
      "Ljava/io/Writer;.close:()V",
      "Ljava/lang/AssertionError;.<init>:()V",
      "Ljava/lang/AssertionError;.<init>:(Ljava/lang/Object;)V",
      "Ljava/lang/Boolean;.booleanValue:()Z",
      "Ljava/lang/Boolean;.parseBoolean:(Ljava/lang/String;)Z",
      "Ljava/lang/Boolean;.valueOf:(Ljava/lang/String;)Ljava/lang/Boolean;",
      "Ljava/lang/Boolean;.valueOf:(Z)Ljava/lang/Boolean;",
      "Ljava/lang/CharSequence;.charAt:(I)C",
      "Ljava/lang/CharSequence;.length:()I",
      "Ljava/lang/CharSequence;.toString:()Ljava/lang/String;",
      "Ljava/lang/Character;.toLowerCase:(C)C",
      "Ljava/lang/Character;.toUpperCase:(C)C",
      "Ljava/lang/Class;.forName:(Ljava/lang/String;)Ljava/lang/Class;",
      "Ljava/lang/Class;.forName:(Ljava/lang/String;ZLjava/lang/ClassLoader;)Ljava/lang/Class;",
      "Ljava/lang/Class;.getClassLoader:()Ljava/lang/ClassLoader;",
      "Ljava/lang/Class;.getDeclaredField:(Ljava/lang/String;)Ljava/lang/reflect/Field;",
      "Ljava/lang/Class;.getDeclaredMethod:(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;",
      "Ljava/lang/Class;.getEnumConstants:()[Ljava/lang/Object;",
      "Ljava/lang/Class;.getField:(Ljava/lang/String;)Ljava/lang/reflect/Field;",
      "Ljava/lang/Class;.getMethod:(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;",
      "Ljava/lang/Class;.getName:()Ljava/lang/String;",
      "Ljava/lang/Class;.getSimpleName:()Ljava/lang/String;",
      "Ljava/lang/Class;.newInstance:()Ljava/lang/Object;",
      "Ljava/lang/Class;.toString:()Ljava/lang/String;",
      "Ljava/lang/ClassCastException;.<init>:(Ljava/lang/String;)V",
      "Ljava/lang/Double;.isNaN:(D)Z",
      "Ljava/lang/Double;.parseDouble:(Ljava/lang/String;)D",
      "Ljava/lang/Double;.valueOf:(D)Ljava/lang/Double;",
      "Ljava/lang/Enum;.<init>:(Ljava/lang/String;I)V",
      "Ljava/lang/Enum;.name:()Ljava/lang/String;",
      "Ljava/lang/Enum;.ordinal:()I",
      "Ljava/lang/Enum;.toString:()Ljava/lang/String;",
      "Ljava/lang/Error;.<init>:(Ljava/lang/String;)V",
      "Ljava/lang/Error;.<init>:(Ljava/lang/Throwable;)V",
      "Ljava/lang/Exception;.<init>:()V",
      "Ljava/lang/Float;.floatValue:()F",
      "Ljava/lang/Float;.valueOf:(F)Ljava/lang/Float;",
      "Ljava/lang/IllegalArgumentException;.<init>:()V",
      "Ljava/lang/IllegalArgumentException;.<init>:(Ljava/lang/String;)V",
      "Ljava/lang/IllegalStateException;.<init>:(Ljava/lang/String;)V",
      "Ljava/lang/IndexOutOfBoundsException;.<init>:(Ljava/lang/String;)V",
      "Ljava/lang/Integer;.highestOneBit:(I)I",
      "Ljava/lang/Integer;.intValue:()I",
      "Ljava/lang/Integer;.parseInt:(Ljava/lang/String;)I",
      "Ljava/lang/Integer;.rotateLeft:(II)I",
      "Ljava/lang/Integer;.toHexString:(I)Ljava/lang/String;",
      "Ljava/lang/Integer;.toString:(I)Ljava/lang/String;",
      "Ljava/lang/Integer;.valueOf:(I)Ljava/lang/Integer;",
      "Ljava/lang/Long;.parseLong:(Ljava/lang/String;)J",
      "Ljava/lang/Long;.valueOf:(J)Ljava/lang/Long;",
      "Ljava/lang/Math;.abs:(F)F",
      "Ljava/lang/Math;.max:(II)I",
      "Ljava/lang/Math;.min:(II)I",
      "Ljava/lang/Math;.min:(JJ)J",
      "Ljava/lang/Math;.pow:(DD)D",
      "Ljava/lang/Math;.signum:(F)F",
      "Ljava/lang/Math;.sqrt:(D)D",
      "Ljava/lang/NullPointerException;.<init>:(Ljava/lang/String;)V",
      "Ljava/lang/Number;.floatValue:()F",
      "Ljava/lang/Number;.intValue:()I",
      "Ljava/lang/Object;.<init>:()V",
      "Ljava/lang/Object;.<init>:()V",
      "Ljava/lang/Object;.equals:(Ljava/lang/Object;)Z",
      "Ljava/lang/Object;.getClass:()Ljava/lang/Class;",
      "Ljava/lang/Object;.hashCode:()I",
      "Ljava/lang/Object;.toString:()Ljava/lang/String;",
      "Ljava/lang/Runtime;.getRuntime:()Ljava/lang/Runtime;",
      "Ljava/lang/Runtime;.availableProcessors:()I",
      "Ljava/lang/RuntimeException;.<init>:()V",
      "Ljava/lang/RuntimeException;.<init>:(Ljava/lang/String;)V",
      "Ljava/lang/RuntimeException;.<init>:(Ljava/lang/String;Ljava/lang/Throwable;)V",
      "Ljava/lang/RuntimeException;.<init>:(Ljava/lang/Throwable;)V",
      "Ljava/lang/StackTraceElement;.getClassName:()Ljava/lang/String;",
      "Ljava/lang/StackTraceElement;.getMethodName:()Ljava/lang/String;",
      "Ljava/lang/String;.<init>:([B)V",
      "Ljava/lang/String;.<init>:([BLjava/lang/String;)V",
      "Ljava/lang/String;.<init>:(Ljava/lang/String;)V",
      "Ljava/lang/String;.charAt:(I)C",
      "Ljava/lang/String;.contains:(Ljava/lang/CharSequence;)Z",
      "Ljava/lang/String;.equals:(Ljava/lang/Object;)Z",
      "Ljava/lang/String;.format:(Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/String;",
      "Ljava/lang/String;.format:(Ljava/util/Locale;Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/String;",
      "Ljava/lang/String;.getBytes:(Ljava/lang/String;)[B",
      "Ljava/lang/String;.hashCode:()I",
      "Ljava/lang/String;.indexOf:(II)I",
      "Ljava/lang/String;.indexOf:(Ljava/lang/String;I)I",
      "Ljava/lang/String;.isEmpty:()Z",
      "Ljava/lang/String;.lastIndexOf:(I)I",
      "Ljava/lang/String;.lastIndexOf:(Ljava/lang/String;)I",
      "Ljava/lang/String;.length:()I",
      "Ljava/lang/String;.replace:(Ljava/lang/CharSequence;Ljava/lang/CharSequence;)Ljava/lang/String;",
      "Ljava/lang/String;.startsWith:(Ljava/lang/String;)Z",
      "Ljava/lang/String;.substring:(I)Ljava/lang/String;",
      "Ljava/lang/String;.substring:(II)Ljava/lang/String;",
      "Ljava/lang/String;.toCharArray:()[C",
      "Ljava/lang/String;.toLowerCase:(Ljava/util/Locale;)Ljava/lang/String;",
      "Ljava/lang/String;.toUpperCase:(Ljava/util/Locale;)Ljava/lang/String;",
      "Ljava/lang/String;.valueOf:(Ljava/lang/Object;)Ljava/lang/String;",
      "Ljava/lang/String;.valueOf:([C)Ljava/lang/String;",
      "Ljava/lang/StringBuilder;.<init>:()V",
      "Ljava/lang/StringBuilder;.<init>:(I)V",
      "Ljava/lang/StringBuilder;.<init>:(Ljava/lang/String;)V",
      "Ljava/lang/StringBuilder;.toString:()Ljava/lang/String;",
      "Ljava/lang/System;.arraycopy:(Ljava/lang/Object;ILjava/lang/Object;II)V",
      "Ljava/lang/System;.currentTimeMillis:()J",
      "Ljava/lang/System;.getProperties:()Ljava/util/Properties;",
      "Ljava/lang/System;.getProperty:(Ljava/lang/String;)Ljava/lang/String;",
      "Ljava/lang/System;.getProperty:(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;",
      "Ljava/lang/System;.identityHashCode:(Ljava/lang/Object;)I",
      "Ljava/lang/System;.nanoTime:()J",
      "Ljava/lang/Thread;.<init>:(Ljava/lang/Runnable;Ljava/lang/String;)V",
      "Ljava/lang/Thread;.currentThread:()Ljava/lang/Thread;",
      "Ljava/lang/Thread;.getStackTrace:()[Ljava/lang/StackTraceElement;",
      "Ljava/lang/ThreadLocal;.<init>:()V",
      "Ljava/lang/Throwable;.<init>:()V",
      "Ljava/lang/Throwable;.getMessage:()Ljava/lang/String;",
      "Ljava/lang/Throwable;.getStackTrace:()[Ljava/lang/StackTraceElement;",
      "Ljava/lang/Throwable;.initCause:(Ljava/lang/Throwable;)Ljava/lang/Throwable;",
      "Ljava/lang/Throwable;.printStackTrace:()V",
      "Ljava/lang/Throwable;.setStackTrace:([Ljava/lang/StackTraceElement;)V",
      "Ljava/lang/Throwable;.toString:()Ljava/lang/String;",
      "Ljava/lang/UnsatisfiedLinkError;.<init>:(Ljava/lang/String;)V",
      "Ljava/lang/ref/ReferenceQueue;.<init>:()V",
      "Ljava/lang/reflect/Field;.get:(Ljava/lang/Object;)Ljava/lang/Object;",
      "Ljava/nio/charset/Charset;.forName:(Ljava/lang/String;)Ljava/nio/charset/Charset;",
      "Ljava/nio/charset/Charset;.name:()Ljava/lang/String;",
      "Ljava/security/Provider;.<init>:(Ljava/lang/String;DLjava/lang/String;)V",
      "Ljava/text/BreakIterator;.getCharacterInstance:()Ljava/text/BreakIterator;",
      "Ljava/text/BreakIterator;.last:()I",
      "Ljava/text/BreakIterator;.setText:(Ljava/lang/String;)V",
      "Ljava/text/SimpleDateFormat;.<init>:(Ljava/lang/String;Ljava/util/Locale;)V",
      "Ljava/util/AbstractCollection;.<init>:()V",
      "Ljava/util/AbstractCollection;.add:(Ljava/lang/Object;)Z",
      "Ljava/util/AbstractCollection;.contains:(Ljava/lang/Object;)Z",
      "Ljava/util/AbstractCollection;.size:()I",
      "Ljava/util/AbstractCollection;.toArray:()[Ljava/lang/Object;",
      "Ljava/util/AbstractCollection;.toArray:([Ljava/lang/Object;)[Ljava/lang/Object;",
      "Ljava/util/AbstractList;.get:(I)Ljava/lang/Object;",
      "Ljava/util/AbstractMap;.<init>:()V",
      "Ljava/util/AbstractMap;.get:(Ljava/lang/Object;)Ljava/lang/Object;",
      "Ljava/util/AbstractMap;.put:(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;",
      "Ljava/util/AbstractQueue;.<init>:()V",
      "Ljava/util/ArrayList;.<init>:()V",
      "Ljava/util/ArrayList;.add:(Ljava/lang/Object;)Z",
      "Ljava/util/ArrayList;.get:(I)Ljava/lang/Object;",
      "Ljava/util/ArrayList;.size:()I",
      "Ljava/util/ArrayList;.toArray:([Ljava/lang/Object;)[Ljava/lang/Object;",
      "Ljava/util/Arrays;.asList:([Ljava/lang/Object;)Ljava/util/List;",
      "Ljava/util/Arrays;.copyOf:([Ljava/lang/Object;I)[Ljava/lang/Object;",
      "Ljava/util/Arrays;.copyOfRange:([BII)[B",
      "Ljava/util/Arrays;.copyOfRange:([Ljava/lang/Object;II)[Ljava/lang/Object;",
      "Ljava/util/Arrays;.fill:([II)V",
      "Ljava/util/Arrays;.fill:([Ljava/lang/Object;IILjava/lang/Object;)V",
      "Ljava/util/Arrays;.sort:([C)V",
      "Ljava/util/Arrays;.toString:([Ljava/lang/Object;)Ljava/lang/String;",
      "Ljava/util/Calendar;.getInstance:(Ljava/util/TimeZone;)Ljava/util/Calendar;",
      "Ljava/util/Collection;.add:(Ljava/lang/Object;)Z",
      "Ljava/util/Collection;.toArray:()[Ljava/lang/Object;",
      "Ljava/util/Collections;.addAll:(Ljava/util/Collection;[Ljava/lang/Object;)Z",
      "Ljava/util/Collections;.newSetFromMap:(Ljava/util/Map;)Ljava/util/Set;",
      "Ljava/util/Collections;.singleton:(Ljava/lang/Object;)Ljava/util/Set;",
      "Ljava/util/Collections;.synchronizedMap:(Ljava/util/Map;)Ljava/util/Map;",
      "Ljava/util/Collections;.unmodifiableList:(Ljava/util/List;)Ljava/util/List;",
      "Ljava/util/Collections;.unmodifiableMap:(Ljava/util/Map;)Ljava/util/Map;",
      "Ljava/util/Collections;.unmodifiableSet:(Ljava/util/Set;)Ljava/util/Set;",
      "Ljava/util/Dictionary;.put:(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;",
      "Ljava/util/EnumMap;.<init>:(Ljava/lang/Class;)V",
      "Ljava/util/EnumSet;.copyOf:(Ljava/util/Collection;)Ljava/util/EnumSet;",
      "Ljava/util/HashMap;.<init>:()V",
      "Ljava/util/HashMap;.<init>:(I)V",
      "Ljava/util/HashMap;.get:(Ljava/lang/Object;)Ljava/lang/Object;",
      "Ljava/util/HashMap;.put:(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;",
      "Ljava/util/HashSet;.<init>:()V",
      "Ljava/util/HashSet;.<init>:(I)V",
      "Ljava/util/HashSet;.<init>:(Ljava/util/Collection;)V",
      "Ljava/util/HashSet;.add:(Ljava/lang/Object;)Z",
      "Ljava/util/HashSet;.contains:(Ljava/lang/Object;)Z",
      "Ljava/util/Iterator;.hasNext:()Z",
      "Ljava/util/Iterator;.next:()Ljava/lang/Object;",
      "Ljava/util/LinkedHashMap;.<init>:()V",
      "Ljava/util/LinkedHashMap;.<init>:(I)V",
      "Ljava/util/LinkedHashMap;.<init>:(IFZ)V",
      "Ljava/util/LinkedHashSet;.<init>:(I)V",
      "Ljava/util/LinkedList;.<init>:()V",
      "Ljava/util/Locale;.<init>:(Ljava/lang/String;Ljava/lang/String;)V",
      "Ljava/util/Locale;.getDefault:()Ljava/util/Locale;",
      "Ljava/util/Map;.containsKey:(Ljava/lang/Object;)Z",
      "Ljava/util/Map;.get:(Ljava/lang/Object;)Ljava/lang/Object;",
      "Ljava/util/Map;.put:(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;",
      "Ljava/util/NoSuchElementException;.<init>:(Ljava/lang/String;)V",
      "Ljava/util/Random;.<init>:()V",
      "Ljava/util/concurrent/Semaphore;.<init>:(I)V",
      "Ljava/util/Set;.add:(Ljava/lang/Object;)Z",
      "Ljava/util/Set;.contains:(Ljava/lang/Object;)Z",
      "Ljava/util/Set;.iterator:()Ljava/util/Iterator;",
      "Ljava/util/TimeZone;.getTimeZone:(Ljava/lang/String;)Ljava/util/TimeZone;",
      "Ljava/util/Timer;.<init>:()V",
      "Ljava/util/TreeSet;.<init>:()V",
      "Ljava/util/TreeSet;.add:(Ljava/lang/Object;)Z",
      "Ljava/util/TreeSet;.contains:(Ljava/lang/Object;)Z",
      "Ljava/util/WeakHashMap;.<init>:()V",
      "Ljava/util/WeakHashMap;.<init>:(I)V",
      "Ljava/util/concurrent/ConcurrentHashMap;.<init>:()V",
      "Ljava/util/concurrent/ConcurrentHashMap;.<init>:(I)V",
      "Ljava/util/concurrent/ConcurrentLinkedQueue;.<init>:()V",
      "Ljava/util/concurrent/CopyOnWriteArraySet;.<init>:()V",
      "Ljava/util/concurrent/LinkedBlockingQueue;.<init>:()V",
      "Ljava/util/concurrent/TimeUnit;.toDays:(J)J",
      "Ljava/util/concurrent/TimeUnit;.toMillis:(J)J",
      "Ljava/util/concurrent/TimeUnit;.toMinutes:(J)J",
      "Ljava/util/concurrent/TimeUnit;.toNanos:(J)J",
      "Ljava/util/concurrent/TimeUnit;.toSeconds:(J)J",
      "Ljava/util/concurrent/ThreadPoolExecutor;.<init>:(IIJLjava/util/concurrent/TimeUnit;Ljava/util/concurrent/BlockingQueue;Ljava/util/concurrent/ThreadFactory;)V",
      "Ljava/util/concurrent/atomic/AtomicBoolean;.<init>:(Z)V",
      "Ljava/util/concurrent/atomic/AtomicInteger;.<init>:()V",
      "Ljava/util/concurrent/atomic/AtomicInteger;.<init>:(I)V",
      "Ljava/util/concurrent/atomic/AtomicInteger;.get:()I",
      "Ljava/util/concurrent/atomic/AtomicInteger;.getAndIncrement:()I",
      "Ljava/util/concurrent/atomic/AtomicLong;.<init>:(J)V",
      "Ljava/util/concurrent/atomic/AtomicReference;.<init>:()V",
      "Ljava/util/concurrent/atomic/AtomicReference;.<init>:(Ljava/lang/Object;)V",
      "Ljava/util/concurrent/atomic/AtomicReferenceArray;.<init>:(I)V",
      "Ljava/util/concurrent/atomic/AtomicReferenceArray;.length:()I",
      "Ljava/util/concurrent/locks/ReentrantLock;.<init>:()V",
      "Ljava/util/concurrent/locks/ReentrantReadWriteLock$ReadLock;.lock:()V",
      "Ljava/util/concurrent/locks/ReentrantReadWriteLock$ReadLock;.unlock:()V",
      "Ljava/util/concurrent/locks/ReentrantReadWriteLock$WriteLock;.lock:()V",
      "Ljava/util/concurrent/locks/ReentrantReadWriteLock$WriteLock;.unlock:()V",
      "Ljava/util/concurrent/locks/ReentrantReadWriteLock;.<init>:()V",
      "Ljava/util/concurrent/locks/ReentrantReadWriteLock;.readLock:()Ljava/util/concurrent/locks/ReentrantReadWriteLock$ReadLock;",
      "Ljava/util/concurrent/locks/ReentrantReadWriteLock;.writeLock:()Ljava/util/concurrent/locks/ReentrantReadWriteLock$WriteLock;",
      "Ljava/util/logging/Logger;.getLogger:(Ljava/lang/String;)Ljava/util/logging/Logger;",
      "Ljava/util/logging/Logger;.log:(Ljava/util/logging/Level;Ljava/lang/String;)V",
      "Ljava/util/logging/Logger;.log:(Ljava/util/logging/Level;Ljava/lang/String;Ljava/lang/Throwable;)V",
      "Ljava/util/regex/Pattern;.compile:(Ljava/lang/String;)Ljava/util/regex/Pattern;",
      "Ljava/util/regex/Pattern;.compile:(Ljava/lang/String;I)Ljava/util/regex/Pattern;",
      "Ljava/util/regex/Pattern;.quote:(Ljava/lang/String;)Ljava/lang/String;",
      "Lredex/$EnumUtils;.values:(I)[Ljava/lang/Integer;",
      // clang-format on
  };

  return method_ref->is_def() &&
         methods.count(method_ref->as_def()->get_deobfuscated_name_or_empty());
}