Verificación en Java (JVM)

Después de que el cargador de clases en la JVM cargue el código de bytes del archivo .class en la máquina, el verificador verifica primero la validez del código de bytes y este proceso se llama verificación . El verificador realiza tantas comprobaciones como sea posible en el enlace para que se pueda eliminar la costosa operación realizada por el intérprete en el tiempo de ejecución. Realza las actuaciones del intérprete.

Algunas de las comprobaciones que realiza el verificador:

  • Variables no inicializadas
  • No se violan las reglas de acceso a datos y métodos privados.
  • Las llamadas a métodos coinciden con la referencia del objeto.
  • No hay desbordamientos o subdesbordamientos de la pila de operandos.
  • Los argumentos de todas las instrucciones de la máquina virtual Java son de tipos válidos.
  • Garantizar que las clases finales no se subclasifiquen y que los métodos finales no se anulen
  • Comprobación de que todas las referencias de campo y de método tengan nombres válidos, clases válidas y un descriptor de tipo válido. ( fuente )

Si alguna de estas comprobaciones falla, JVM arroja un error «java.lang.VerifyError». Sin embargo, podemos deshabilitar estas comprobaciones usando

java -noverify VerifyGeekFile

Uno podría pensar cómo se podría haber manipulado un programa ya que el compilador verifica estas validaciones anteriores antes de generar el archivo .class. Pero el archivo de clase es vulnerable a cambios antes de que JVM lo cargue. El código de bytes utilizado en el archivo de clase está bien documentado y alguien que tenga algún conocimiento de hexadecimal puede cambiar los valores de los códigos hexadecimales en el archivo .class y así cambiar el comportamiento del programa.
Por ejemplo: los applets en los navegadores web no descargan el código fuente, sino que descargan archivos de clase precompilados. El navegador de su computadora determina si este archivo de clase es confiable para ejecutarse o si el archivo ha sido explotado por un «compilador hostil».

Considere este programa simple

// A Java program to demonstrate working
// of the verification process
  
class VerifyGeekFile
{
    // your initial bank bal
    private float bal;
  
    // Method to deposit money
    float depositBalance(int bal)
    {
        int myBal = bal;
        this.bal += myBal;
        return this.bal;
    }
  
    // Driver Method
    public static void main(String[] args)
    {
        VerifyGeekFile obj = new VerifyGeekFile();
        System.out.println(obj.depositBalance(4000));
    }
}
Output
 4000.0

Luego ejecute esto en la línea de comando para ver el código de bytes en forma mnemotécnica: –

javap -c VerifyGeekFile

Producción :

float depositBalance(int);
    Code:
       0: iload_1
       1: istore_2
       2: aload_0
       3: dup
       4: getfield      #2                  // Field bal:F
       7: iload_2
       8: i2f
       9: fadd
      10: putfield      #2                  // Field bal:F
      13: aload_0
      14: getfield      #2                  // Field bal:F
      17: freturn

Aquí, si cambiamos el valor inicial de myBal o lo dejamos sin inicializar usando un editor hexadecimal, se devuelven resultados inesperados. El proceso de verificación de Java nos protege de todos estos escollos.

Referencias:
http://www.informit.com/articles/article.aspx?p=1187967&seqNum=2
https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms -4.10

Publicación traducida automáticamente

Artículo escrito por rishabh jindal 1 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *