Dotfuscator User's Guide
Application Notification

All Checks provide a way for the application to be informed of the check's result. This process is called Application Notification, and the application code that receives the result is known as the Sink.

The Sink may be a writeable boolean-valued property or field, or it may be a method or delegate with the signature void(bool). After a Check, the generated code sets the boolean value to true if the Check detected what it was looking for (e.g., tampering); false if not. The application is free to react in any way in response to a tamper notification.

Note: Shelf Life Checks have two types of Application Notifications, and their method and delegate Sinks may take two string values rather than a single boolean value. For details, see the Shelf Life Check section.

Sinks are defined by three properties of the Check's attribute:

Sink Types

The possible Sinks are given in-code by the SinkElements enumeration.

None

The Check will not call to the application code. This is the default.

Method

The Check will call a method with the signature void(bool).

InsertTamperCheckAttribute Usage with Method Sink
Copy Code
internal class TamperMethodSample
{
    [InsertTamperCheck(
        ApplicationNotificationSinkElement = SinkElements.Method,
        ApplicationNotificationSinkName = "CheckTamperState"
    )]
    public void Verify()
    {
        // Dotfuscator will add Tamper detection and notification code here
    }
    
    public void CheckTamperState(bool wasTampered)
    {
        if (wasTampered)
        {
            Console.WriteLine("App HAS been tampered with");
        }
        else
        {
            Console.WriteLine("App has not been tampered with");
        }
    }

    public static void Main(string[] args)
    {
        var sample = new TamperMethodSample();
        sample.Verify();
    }
}

Field

The Check will set a writable bool field.

InsertTamperCheckAttribute Usage with Field Sink
Copy Code
internal class TamperFieldSample
{
    private bool instanceTamperFlag;

    [InsertTamperCheck(
        ApplicationNotificationSinkElement = SinkElements.Field,
        ApplicationNotificationSinkName = "instanceTamperFlag"
    )]
    public void Verify()
    {
        // Dotfuscator will add Tamper detection and notification code here
    }

    public void CheckTamperState()
    {
        if (instanceTamperFlag)
        {
            Console.WriteLine("App HAS been tampered with");
        }
        else
        {
            Console.WriteLine("App has not been tampered with");
        }
    }

    public static void Main(string[] args)
    {
        var sample = new TamperFieldSample();
        sample.Verify(); // sets instanceTamperFlag to check result
        sample.CheckTamperState(); // uses instanceTamperFlag
    }
}

Delegate

The Check will call a void(bool) delegate held in a delegate field.

InsertTamperCheckAttribute Usage with Delegate Sink
Copy Code
internal class TamperDelegateSample
{
    public delegate void TamperNotificationDelegate(bool isTampered);
    public TamperNotificationDelegate TamperedDelegate;

    [InsertTamperCheck(
        ApplicationNotificationSinkElement = SinkElements.Delegate,
        ApplicationNotificationSinkName = "TamperedDelegate"
    )]
    public void Verify()
    {
        // Dotfuscator will add Tamper detection and notification code here
    }

    public static void Main(string[] args)
    {
        var sample = new TamperDelegateSample();
        sample.TamperedDelegate = isTampered =>
        {
            if (isTampered)
            {
                Console.WriteLine("App HAS been tampered with");
            }
            else
            {
                Console.WriteLine("App has not been tampered with");
            }
        };
        sample.Verify();
    }
}

Property

The Check will set a writable bool field.

InsertTamperCheckAttribute Usage with Property Sink
Copy Code
internal class TamperPropertySample
{
    public bool IsTampered { get; private set; }

    [InsertTamperCheck(
        ApplicationNotificationSinkElement = SinkElements.Property,
        ApplicationNotificationSinkName = "IsTampered"
    )]
    public void Verify()
    {
        // Dotfuscator will add Tamper detection and notification code here
    }

    public static void Main(string[] args)
    {
        var sample = new TamperPropertySample();
        sample.Verify();
        if (sample.IsTampered)
        {
            Console.WriteLine("App HAS been tampered with");
        }
        else
        {
            Console.WriteLine("App has not been tampered with");
        }
    }
}

Method Argument

The Check will call a void(bool) delegate held in a parameter to the attributed method.

InsertTamperCheckAttribute Usage with Property Sink
Copy Code
internal class TamperMethodArgumentSample
{
    public delegate void TamperNotificationDelegate(bool isTampered);

    [InsertTamperCheck(
        ApplicationNotificationSinkElement = SinkElements.MethodArgument,
        ApplicationNotificationSinkName = "foo"
    )]
    public void Verify(TamperNotificationDelegate foo)
    {
        // Dotfuscator will add Tamper detection and notification code here
    }

    public static void Main(string[] args)
    {
        var sample = new TamperMethodArgumentSample();
        sample.Verify(isTampered =>
        {
            if (isTampered)
            {
                Console.WriteLine("App HAS been tampered with");
            }
            else
            {
                Console.WriteLine("App has not been tampered with");
            }
        });
    }
}

DefaultAction

The Check will not call to the application code. Instead, a predetermined set of logic will be executed:

Sink Scopes

With the exception of the Method Argument Sink type, Sinks may be defined as either static members or as instance members of types within the application.

Static Sinks

If the Sink specified is a static member, it must simply be accessible from the attributed method. The Sink will be used as a static member (i.e., without being tied to a particular object instance).

Instance Sinks

If the Sink specified is an instance member, it must be defined on the same type as the attributed method. The Sink will be used as a member of same instance that will run the attributed method. See the Field sample code above for an example.

See Also

Attribute Reference

 

 


© 2016 PreEmptive Solutions, LLC. All Rights Reserved.

www.preemptive.com