Use new verifier function to lazily check.
authorRodrigo Kumpera <kumpera@gmail.com>
Mon, 20 Sep 2010 22:26:12 +0000 (19:26 -0300)
committerRodrigo Kumpera <kumpera@gmail.com>
Mon, 20 Sep 2010 22:31:14 +0000 (19:31 -0300)
* class.c: The typeref table is now lazily verified thanks
to some awesome obfuscators that love to produce junk.
So it has to be checked everytime before usage instead of
at loading time.

mono/metadata/class.c

index 5d0a8cc8289fbcef70a2091aae9c98930f1fae99..170f844a87ae29db619736e848e64a2911f0c325 100644 (file)
@@ -83,13 +83,19 @@ void (*mono_debugger_class_loaded_methods_func) (MonoClass *klass) = NULL;
 MonoClass *
 mono_class_from_typeref (MonoImage *image, guint32 type_token)
 {
 MonoClass *
 mono_class_from_typeref (MonoImage *image, guint32 type_token)
 {
+       MonoError error;
        guint32 cols [MONO_TYPEREF_SIZE];
        MonoTableInfo  *t = &image->tables [MONO_TABLE_TYPEREF];
        guint32 idx;
        const char *name, *nspace;
        MonoClass *res;
        MonoImage *module;
        guint32 cols [MONO_TYPEREF_SIZE];
        MonoTableInfo  *t = &image->tables [MONO_TABLE_TYPEREF];
        guint32 idx;
        const char *name, *nspace;
        MonoClass *res;
        MonoImage *module;
-       
+
+       if (!mono_verifier_verify_typeref_row (image, (type_token & 0xffffff) - 1, &error)) {
+               mono_trace_warning (MONO_TRACE_TYPE, "Failed to resolve typeref from %s due to '%s'", image->name, mono_error_get_message (&error));
+               return NULL;
+       }
+
        mono_metadata_decode_row (t, (type_token&0xffffff)-1, cols, MONO_TYPEREF_SIZE);
 
        name = mono_metadata_string_heap (image, cols [MONO_TYPEREF_NAME]);
        mono_metadata_decode_row (t, (type_token&0xffffff)-1, cols, MONO_TYPEREF_SIZE);
 
        name = mono_metadata_string_heap (image, cols [MONO_TYPEREF_NAME]);
@@ -6404,12 +6410,20 @@ mono_class_name_from_token (MonoImage *image, guint32 type_token)
        }
 
        case MONO_TOKEN_TYPE_REF: {
        }
 
        case MONO_TOKEN_TYPE_REF: {
+               MonoError error;
                guint32 cols [MONO_TYPEREF_SIZE];
                MonoTableInfo  *t = &image->tables [MONO_TABLE_TYPEREF];
                guint tidx = mono_metadata_token_index (type_token);
 
                if (tidx > t->rows)
                        return g_strdup_printf ("Invalid type token 0x%08x", type_token);
                guint32 cols [MONO_TYPEREF_SIZE];
                MonoTableInfo  *t = &image->tables [MONO_TABLE_TYPEREF];
                guint tidx = mono_metadata_token_index (type_token);
 
                if (tidx > t->rows)
                        return g_strdup_printf ("Invalid type token 0x%08x", type_token);
+
+               if (!mono_verifier_verify_typeref_row (image, tidx - 1, &error)) {
+                       char *msg = g_strdup_printf ("Invalid type token 0x%08x due to '%s'", type_token, mono_error_get_message (&error));
+                       mono_error_cleanup (&error);
+                       return msg;
+               }
+
                mono_metadata_decode_row (t, tidx-1, cols, MONO_TYPEREF_SIZE);
                name = mono_metadata_string_heap (image, cols [MONO_TYPEREF_NAME]);
                nspace = mono_metadata_string_heap (image, cols [MONO_TYPEREF_NAMESPACE]);
                mono_metadata_decode_row (t, tidx-1, cols, MONO_TYPEREF_SIZE);
                name = mono_metadata_string_heap (image, cols [MONO_TYPEREF_NAME]);
                nspace = mono_metadata_string_heap (image, cols [MONO_TYPEREF_NAMESPACE]);
@@ -6440,6 +6454,7 @@ mono_assembly_name_from_token (MonoImage *image, guint32 type_token)
                        return g_strdup (image->assembly_name);
                return g_strdup_printf ("%s", image->name ? image->name : "[Could not resolve assembly name");
        case MONO_TOKEN_TYPE_REF: {
                        return g_strdup (image->assembly_name);
                return g_strdup_printf ("%s", image->name ? image->name : "[Could not resolve assembly name");
        case MONO_TOKEN_TYPE_REF: {
+               MonoError error;
                MonoAssemblyName aname;
                guint32 cols [MONO_TYPEREF_SIZE];
                MonoTableInfo  *t = &image->tables [MONO_TABLE_TYPEREF];
                MonoAssemblyName aname;
                guint32 cols [MONO_TYPEREF_SIZE];
                MonoTableInfo  *t = &image->tables [MONO_TABLE_TYPEREF];
@@ -6448,6 +6463,11 @@ mono_assembly_name_from_token (MonoImage *image, guint32 type_token)
                if (idx > t->rows)
                        return g_strdup_printf ("Invalid type token 0x%08x", type_token);
        
                if (idx > t->rows)
                        return g_strdup_printf ("Invalid type token 0x%08x", type_token);
        
+               if (!mono_verifier_verify_typeref_row (image, idx - 1, &error)) {
+                       char *msg = g_strdup_printf ("Invalid type token 0x%08x due to '%s'", type_token, mono_error_get_message (&error));
+                       mono_error_cleanup (&error);
+                       return msg;
+               }
                mono_metadata_decode_row (t, idx-1, cols, MONO_TYPEREF_SIZE);
 
                idx = cols [MONO_TYPEREF_SCOPE] >> MONO_RESOLTION_SCOPE_BITS;
                mono_metadata_decode_row (t, idx-1, cols, MONO_TYPEREF_SIZE);
 
                idx = cols [MONO_TYPEREF_SCOPE] >> MONO_RESOLTION_SCOPE_BITS;