Skip to main content
Version: 2023.4

5.2. Code Inlining

5.2.1. Introduction

Method bodies can be inlined to their call sites during obfuscation. Please take a look at example (C#):

Example 5.1. Before obfuscation

using System;
using System.Reflection;

class Program
{
static void Main(string[] args)
{
Console.WriteLine("Inlining test");
SecretMethod();
}

[Obfuscation(Feature = "inline", Exclude = false)]
static void SecretMethod()
{
Console.WriteLine("Secret");
}
}

Example 5.2. After obfuscation

using System;

class Program
{
static void Main(string[] args)
{
Console.WriteLine("Inlining test");
Console.WriteLine("Secret");
}
}

Code inlining brings obvious security benefits:

  • Once method is inlined, it's no longer a subject of hacker's special attention

  • Call site gets larger as it takes inlined instructions of the method. This makes code analysis a harder task for an intruder

Code inlining may be useful in such scenarios as licensing checks and know-how algorithms.

5.2.2. Instructions

To use the method inlining feature, you should apply an attribute to the method you want to inline. In order to do that, you can use the instructions below.

Instructions on enabling method inlining

  1. Open the source code of a method you want to inline

  2. Add a custom attribute as shown below (C#):

    using System;
    using System.Reflection;

    class YourClass
    {
    [Obfuscation(Feature = "inline", Exclude = false)]
    void YourMethod()
    {
    ...
    }
    }

    For Visual Basic .NET:

    Imports System
    Imports System.Reflection

    Class YourClass

    <Obfuscation(Feature:="inline", Exclude:=False)>
    Sub YourMethod()
    ...
    End Sub

    End Class

5.2.3. Method Flattening

Method flattening is another way to control whether code inlining is applied. For a flattened method, every call inside the method will be inlined, if possible.

The following methods are not inlined during flattening:

  • Methods annotated with [MethodImpl(MethodImplOptions.NoInlining)] attribute
  • Methods annotated with [Obfuscation(Feature = "inline", Exclude = true)] directive. Note that Exclude property is set to true. It excludes the method from being inlined
  • Methods from other assemblies
  • Methods invoked by polymorphic calls (e.g. virtual methods of a class)
  • Dynamically invoked methods (via C# dynamic keyword or via VB.NET late binding)

All other methods are inlined during flattening. Please take a look at example (C#):

Example 5.3. Before obfuscation

using System;
using System.Reflection;

class Program
{
[Obfuscation(Feature = "flatten", Exclude = false)]
static void Main(string[] args)
{
Console.WriteLine("Flattening test");
SecretMethod1();
SecretMethod2();
}

static void SecretMethod1()
{
Console.WriteLine("Secret 1");
}

static void SecretMethod2()
{
Console.WriteLine("Secret 2");
}
}

Example 5.4. After obfuscation

using System;

class Program
{
static void Main(string[] args)
{
Console.WriteLine("Flattening test");
Console.WriteLine("Secret 1");
Console.WriteLine("Secret 2");
}
}

To use the method flattening feature, you should apply a corresponding obfuscation directive to the method you want to flatten. In order to do that, you can use the instructions below.

Instructions on enabling method flattening

  1. Open the source code of a method you want to flatten

  2. Add a custom attribute as shown below (C#):

    using System;
    using System.Reflection;

    class YourClass
    {
    [Obfuscation(Feature = "flatten", Exclude = false)]
    void YourMethod()
    {
    ...
    }
    }

    For Visual Basic .NET:

    Imports System
    Imports System.Reflection

    Class YourClass

    <Obfuscation(Feature:="flatten", Exclude:=False)>
    Sub YourMethod()
    ...
    End Sub

    End Class