All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.eg.agent.compile.visitor.EgClassVisitor Maven / Gradle / Ivy

package com.eg.agent.compile.visitor;

import com.eg.agent.compile.EGLogger;

/**
 * @author janakiraman.k
 *
 */
import com.eg.agent.compile.RewriterUtils;
import com.eg.agent.compile.HaltBuildException;
import com.eg.agent.compile.InstrumentationContext;
import com.eg.objectweb.asm.ClassAdapter;
import com.eg.objectweb.asm.ClassVisitor;
import com.eg.objectweb.asm.FieldVisitor;
import com.eg.objectweb.asm.MethodVisitor;
import com.eg.objectweb.asm.commons.GeneratorAdapter;

import java.util.UUID;

public class EgClassVisitor extends ClassAdapter {
    private static String buildId;
    private final InstrumentationContext context;
    private final EGLogger log;

    public EgClassVisitor(ClassVisitor cv, InstrumentationContext context, EGLogger log) {
        super(cv);
        this.context = context;
        this.log = log;
    }

    public static String getBuildId() {
        if (buildId == null) {
            buildId = UUID.randomUUID().toString();
        }

        return buildId;
    }

    public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
        if ((this.context.getClassName().equals("com/eg/agent/android/eGAndroidAgent")) && (name.equals("isInstrumented"))) {
            return new EgMethodVisitor(super.visitMethod(access, name, desc, signature, exceptions), access, name, desc);
        }

        if ((this.context.getClassName().equals("com/eg/agent/android/harvest/crash/CrashData")) && (name.equals("getBuildId"))) {
            return new BuildIdMethodVisitor(super.visitMethod(access, name, desc, signature, exceptions), access, name, desc);
        }

        if ((this.context.getClassName().equals("com/eg/agent/android/BaseAndroidAgent")) && (name.equals("pokeCanary"))) {
            return new CanaryMethodVisitor(super.visitMethod(access, name, desc, signature, exceptions), access, name, desc);
        }

        return super.visitMethod(access, name, desc, signature, exceptions);
    }

    public FieldVisitor visitField(int access, String name, String desc, String signature, Object value) {
        if ((this.context.getClassName().equals("com/eg/agent/android/EGAgent")) && (name.equals("VERSION")) &&
                (!value.equals(RewriterUtils.getVersion()))) {
            throw new HaltBuildException("EG Error: Your agent and class rewriter versions do not match: agent = " + value + " class rewriter = " + RewriterUtils.getVersion() + ".  You probably need to update one of these components.  If you're using gradle and just updated, run gradle -stop to restart the daemon.");
        }

        return super.visitField(access, name, desc, signature, value);
    }

    private final class CanaryMethodVisitor extends GeneratorAdapter {
        private boolean foundCanaryAlive = false;

        public CanaryMethodVisitor(MethodVisitor mv, int access, String name, String desc) {
            super(mv, access, name, desc);
        }

        public void visitMethodInsn(int opcode, String owner, String name, String desc) {
            if (name.equals("canaryMethod"))
                this.foundCanaryAlive = true;
        }

        public void visitEnd() {
            if (this.foundCanaryAlive) {
                //log.info("Found canary alive");
            } else {
                //log.info("Evidence of Proguard detected, sending mapping.txt");
                /*Proguard proguard = new Proguard(EgClassVisitor.this.log);
                proguard.findAndSendMapFile();*/
            }
        }
    }

    private final class EgMethodVisitor extends GeneratorAdapter {
        public EgMethodVisitor(MethodVisitor mv, int access, String name, String desc) {
            super(mv, access, name, desc);
        }

        public void visitCode() {
            super.visitInsn(4);
            super.visitInsn(172);

           //log.info("Marking EG agent as instrumented");
           context.markModified();
        }
    }

    private final class BuildIdMethodVisitor extends GeneratorAdapter {
        public BuildIdMethodVisitor(MethodVisitor mv, int access, String name, String desc) {
            super(mv, access, name, desc);
        }

        public void visitCode() {
            super.visitLdcInsn(EgClassVisitor.getBuildId());
            super.visitInsn(176);

           //log.info("Setting build identifier to " + EgClassVisitor.getBuildId());
           context.markModified();
        }
    }
}





© 2015 - 2025 Weber Informatics LLC | Privacy Policy