{"record":{"id":"f2674c73c705e025","repo":"icsharpcode/ILSpy","slug":"invalid-metadata-token","errorCode":null,"errorMessage":"Invalid metadata token","messagePattern":"Invalid metadata token","errorType":"exception","errorClass":"BadImageFormatException","httpStatus":null,"severity":"error","filePath":"ICSharpCode.Decompiler/IL/ILReader.cs","lineNumber":223,"sourceCode":"\t\t\t\tv.InitialValueIsInitialized = body.LocalVariablesInitialized;\r\n\t\t\t\tv.UsesInitialValue = true;\r\n\t\t\t}\r\n\t\t\tthis.mainContainer = new BlockContainer(expectedResultType: methodReturnStackType);\r\n\t\t\tthis.blocksByOffset.Clear();\r\n\t\t\tthis.importQueue.Clear();\r\n\t\t\tthis.isBranchTarget = new BitSet(reader.Length);\r\n\t\t\tthis.variableByExceptionHandler.Clear();\r\n\t\t}\r\n\r\n\t\tEntityHandle ReadAndDecodeMetadataToken()\r\n\t\t{\r\n\t\t\tint token = reader.ReadInt32();\r\n\t\t\tif (token <= 0)\r\n\t\t\t{\r\n\t\t\t\t// SRM uses negative tokens as \"virtual tokens\" and can get confused\r\n\t\t\t\t// if we manually create them.\r\n\t\t\t\t// Row-IDs < 1 are always invalid.\r\n\t\t\t\tthrow new BadImageFormatException(\"Invalid metadata token\");\r\n\t\t\t}\r\n\t\t\tvar handle = MetadataTokens.EntityHandle(token);\r\n\t\t\tif (handle.IsNil)\r\n\t\t\t{\r\n\t\t\t\t// The runtime will crash with a BadImageFormatException when it encounters a row-ID of 0.\r\n\t\t\t\t// We assume the code following this instruction to be unreachable.\r\n\t\t\t\tthrow new BadImageFormatException(\"Invalid metadata token\");\r\n\t\t\t}\r\n\t\t\treturn handle;\r\n\t\t}\r\n\r\n\t\tIType ReadAndDecodeTypeReference()\r\n\t\t{\r\n\t\t\tvar typeReference = ReadAndDecodeMetadataToken();\r\n\t\t\treturn module.ResolveType(typeReference, genericContext);\r\n\t\t}\r\n\r\n\t\tIMethod ReadAndDecodeMethodReference()\r","sourceCodeStart":205,"sourceCodeEnd":241,"githubUrl":"https://github.com/icsharpcode/ILSpy/blob/60c08fcb74fcc183130f73c861ed35cf944d0bf1/ICSharpCode.Decompiler/IL/ILReader.cs#L205-L241","documentation":"BadImageFormatException thrown by ReadAndDecodeMetadataToken when the 4-byte token read from the IL stream is <= 0. SRM (System.Reflection.Metadata) uses negative integers as 'virtual tokens' and gets confused if one is fabricated, and row ids below 1 are never valid, so a non-positive token signals a corrupted or truncated method body.","triggerScenarios":"Decompiling an assembly whose IL stream contains a garbage/negative token operand: truncated method body, hand-crafted malformed IL, or an obfuscated binary with tampered token bytes.","commonSituations":"Obfuscated or packed assemblies; assemblies corrupted on disk or in transit; IL emitted by a buggy/illicit code generator writing invalid token operands.","solutions":["Treat the assembly as untrusted input and wrap decompilation in try/catch for BadImageFormatException.","Verify the file is a valid managed PE before decompiling (e.g. PEReader.IsEntireImageAvailable / check the PE header).","Re-acquire a clean copy of the assembly if the stream is truncated."],"exampleFix":"// before\nvar result = decompiler.DecompileAssembly(assemblyPath);\n\n// after\ntry\n{\n    var result = decompiler.DecompileAssembly(assemblyPath);\n}\ncatch (BadImageFormatException ex)\n{\n    logger.Warn($\"Corrupt assembly {assemblyPath}: {ex.Message}\");\n}","handlingStrategy":"try-catch","validationCode":"bool IsValidPe(string path)\n{\n    try { using var pe = new PEReader(File.OpenRead(path)); return pe.PEHeaders != null; }\n    catch { return false; }\n}","typeGuard":null,"tryCatchPattern":"try { var code = decompiler.DecompileTypeAsString(typeName); }\ncatch (BadImageFormatException ex) { logger.Warn($\"Corrupt IL in {assemblyPath}: {ex.Message}\"); }","preventionTips":["Treat decompiled assemblies as untrusted input and catch BadImageFormatException.","Validate the PE header before decompiling when you preprocess inputs.","Re-download a clean copy when a stream looks truncated."],"tags":["il-reader","metadata-token","bad-image","corruption"],"backgroundTag":null,"analyzedSha":"60c08fcb74fcc183130f73c861ed35cf944d0bf1","analyzedAt":"2026-08-13T11:34:51.223Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}