Call Hiding Enterprise
Decompilers and reverse-engineering tools trace which method calls which to reconstruct program flow. Call hiding breaks that trace: static analysis can no longer determine the real target of a call without running the application. Reversers lose the ability to follow program flow without executing the code.
Usage
| CLI | MSBuild | Default |
|---|---|---|
| (enabled by default at Enterprise) | (enabled by default) | On |
--no-call-hiding | <DemeanorNoCallHiding>true</DemeanorNoCallHiding> | Disable |
--proxy-threshold <N> | <DemeanorProxyThreshold>16</DemeanorProxyThreshold> | Min IL body size |
Before & After
public string FormatReceipt(int quantity, TaxRegion region)
{
decimal total = CalculateTotal(quantity, region);
return $"Receipt: ...";
}string a(int a, h a)
{
decimal value = k.a(this, a, a);
// k.a hides the real call target
...
}Real ILSpy output. The direct call to CalculateTotal is gone; the decompiler shows a routed call whose real target cannot be determined without running the application. Static call-graph analysis is broken.
Tuning
The --proxy-threshold option (default 16 bytes) sets the minimum size for an in-assembly call to be eligible. Very small methods are left as direct calls so the JIT can still inline them. Cross-assembly calls are always covered.
When to Disable
- Stack trace readability — call hiding adds an extra frame to call stacks. This can make crash reports harder to interpret.
- Profiling — performance profilers may attribute time to the routing site instead of the actual callee.
Ready to protect your .NET code?