icsharpcode/ILSpy · error · BadImageFormatException
Invalid calli metadata token
Error message
Invalid calli metadata token
What it means
BadImageFormatException (wrapping InvalidCastException) thrown by DecodeCallIndirect when the calli instruction's operand token cannot be cast to StandaloneSignatureHandle. A calli instruction must reference a function-pointer standalone signature; any other table type for its operand is invalid IL.
Source
Thrown at ICSharpCode.Decompiler/IL/ILReader.cs:1845
}
arguments[0] = firstArgumentInstruction;
}
// arguments is in reverse order of the Pop calls, thus
// arguments is now in the correct evaluation order.
return arguments;
}
}
DecodedInstruction DecodeCallIndirect()
{
StandaloneSignatureHandle signatureHandle;
try
{
signatureHandle = (StandaloneSignatureHandle)ReadAndDecodeMetadataToken();
}
catch (InvalidCastException ex)
{
throw new BadImageFormatException("Invalid calli metadata token", ex);
}
var (header, fpt) = module.DecodeMethodSignature(signatureHandle, genericContext);
var functionPointer = Pop(StackType.I);
int firstArgument = header.IsInstance ? 1 : 0;
var arguments = new ILInstruction[firstArgument + fpt.ParameterTypes.Length];
for (int i = fpt.ParameterTypes.Length - 1; i >= 0; i--)
{
arguments[firstArgument + i] = Pop(fpt.ParameterTypes[i].GetStackType());
}
if (firstArgument == 1)
{
arguments[0] = Pop();
}
// arguments is in reverse order of the Pop calls, thus
// arguments is now in the correct evaluation order.
var call = new CallIndirect(
header.IsInstance,
header.HasExplicitThis,
View on GitHub (pinned to 60c08fcb74)
Solutions
- Catch BadImageFormatException during decompilation and mark the method unreadable.
- Cross-check the token's table against StandaloneSignature before decompiling if you preprocess metadata.
- Use a clean copy of the assembly if tampering is suspected.
Example fix
// before
var code = decompiler.DecompileTypeAsString(typeName);
// after
try
{
var code = decompiler.DecompileTypeAsString(typeName);
}
catch (BadImageFormatException ex) when (ex.Message.Contains("calli"))
{
logger.Warn($"Invalid calli token in {typeName}: {ex.Message}");
} Defensive patterns
Strategy: try-catch
Validate before calling
void VerifyCalliTokens(string path)
{
using var pe = new PEReader(File.OpenRead(path));
var md = pe.GetMetadataReader();
// calli operands must be StandaloneSignature (table 0x11); flag any whose table byte differs
} Try / catch
try { var code = decompiler.DecompileTypeAsString(typeName); }
catch (BadImageFormatException ex) when (ex.Message.Contains("calli")) { logger.Warn($"Invalid calli signature token: {ex.Message}"); } Prevention
- Catch BadImageFormatException during decompilation and degrade gracefully.
- When preprocessing, confirm calli operands resolve to StandaloneSignature rows.
- Suspect obfuscation when calli tokens point at unexpected tables.
When it happens
Trigger: A calli instruction whose operand token is not a StandaloneSignature (e.g. points at a MethodDef, MethodSpec, or TypeSpec row); corrupt or hand-edited IL.
Common situations: Obfuscated assemblies that rewrite calli operands; damaged metadata streams; IL generated by tools that emit the wrong table for function-pointer signatures.
Related errors
AI-assisted analysis of icsharpcode/ILSpy@60c08fcb74 (2026-08-13).
Data as JSON: /api/errors/688dbc622ff5c699.
Report an issue: GitHub.