Showing posts with label C#. Show all posts
Showing posts with label C#. Show all posts

Monday, 20 October 2014

.NET Obfuscation using Dotfuscator for Source Code Protection

Do you know that .NET Compiled code can be revert back to C# and VB.NET Source code. Yes it is possible by using decompiler we can get the original source code, then what about security. We can use .NET Obfuscation using dotfuscator for source code protection ...
image
All the lanugage compilers exists nowadays are producing the byte code or intermediate code that could be understandable to thier language interpreters. Microsoft .NET compiler converts the C# and VB.NET source code to MSIL (Microsoft Intermediate Languages). Java compiler converts the Java source code to byte code called class file and.
Now intersting part is there are lots of decompilers are available in market like Reflector for .NET, Dcafe for Java, hackers can get back the source code anytime from intermediate code using these decompilers. Now how we provide security for the source code. Here is the solution using ... Obfuscation  and Obfuscation Tools like Dotfuscator.
Overview
  1. Outline
  2. Define the problem
  3. Define Obfuscation
  4. Why Obfuscate?
  5. Layout Obfuscation
  6. How are we going to do it?
  7. Alternatives
  8. Conclusion
1. Outline and 2. Define the problem
Security is becoming increasingly important in the world of software. This session will discuss the various software security mechanisms focusing on applications built with .NET or Java. Topics covered include obfuscation and encryption. This session will also discuss common security vulnerabilities and provide tips and best practices to protect our code.
How.Net code is compiled ? image
image
3. Define Obfuscation
  • Obfuscate – “to confuse”
  • Behavior preserving transformations on code that preserve function but reduce readability or understandability
    •Hide what’s required, remove the rest
    •Confuse observers, but give Runtime Environment the same delivery
    •How do we confuse the reader?
4. Why Obfuscate? •IP should be protected
•Obfuscation provides important "trade secret" level protection
•Also, obfuscating may provide more legal options, since it indicates that the IP owner has taken measures to secure the IP
Code obfuscation
  • Obfuscating Arrays
image
  • Obfuscating Class
  • Obfuscating Variables
image 
Reverse engineering extracts piece of program
Obfuscation1
Obfuscation makes reverse engineering difficult
Obfuscation2 
5. Layout Obfuscation
Remove comments, identifiers
Scramble identifiers
Limited format changes
Method overloading
getPayroll() becomes a()
makeDeposit(float amount)becomes a(float a)
sendPayment(String dest) becomes a(String a)
How do we confuse the reader?
  • Control Flow Obfuscation
       - Rearranges control flow structures to make the application's logic harder to follow.
  • Removal of Unused Members
       - Removes members that are not used from the IL.
  • String Encryption
       - Encrypts strings so that they do not appear in plain text in the IL.
  • Data obfuscation
Control Flow Obfuscation
  • Change the flow of the program
  • Break the link between the original code and the obfuscated code
  • §Must ensure doesn’t introduce any bugs
  • For example, if or while statements can be transformed into other statements that are logically equivalent but more complex appearing by using the rules of logic. An obfuscator might also insert GoTo statements and labels to turn your neat logic into "spaghetti code" to further confuse human readers.
Removal of Unused Members An obfuscator can also evaluate your application's entire source code to determine whether there are any methods that are actually unused, and if so, remove them from the obfuscated assembly. This situation can easily arise if you've developed code with a code generator or used classes from a general-purpose utility library. For example: you might have collection classes with the full range of methods that any collection should support, but only use a small fraction of those methods in your application. An obfuscator can remove the unused code, making the remaining code harder to understand and shrinking the program as a beneficial side effect.
String Encryption String constants and literal strings in your .NET source code appear unchanged in your compiled .NET assemblies. Such strings can provide valuable clues for anyone trying to reverse-engineer your code. For example, an attacker trying to break a licensing routine would first focus attention on strings having to do with licensing to locate the appropriate section of code. Obfuscators can make this more difficult by encrypting the strings in the .NET assembly. This is accomplished by inserting a decryption routine into the assembly and calling the decryption code at runtime to return the original strings.
Data obfuscation
Storage obfuscation
    -Alters how data is stored in memory
     E.g. Making local variables to global and vice versa.
Aggregation obfuscation
    -Spliting an array into several array.
.NET Obfuscator Benefits: Protects and Improves .NET Code
  • Dotfuscator Professional obfuscator significantly enhances source code security.
. NET rich intermediate language is focused on application flexibility and inherently provides significant information on how an application was written. Because of this, .NET applications are more prone to reverse-engineering attack than most previous computer programs. Dotfuscator Pro includes state-of-the-art obfuscation technology to protect .NET applications - securing the important intellectual property contained within.
  • Dotfuscator Professional decreases the size of your .NET program.
Dotfuscator analyzes your application and figures out exactly which parts of your program you're really using (down to the method level!). From there it can parse out those pieces leaving you with the smallest executable possible.
  • Dotfuscator Professional improves run-time performance.
By removing unneeded program elements and renaming identifiers to small names, Dotfuscator .NET obfuscator can actually speed up programs.
  • Dotfuscator Professional provides tamper detection and notification.
Dotfuscator's Tamper Detection and Notification service notifies your organization when one of your applications detects tampering. Tampered applications cost millions in revenue to suppliers and introduce material security and liability risks to consumers.
  • Assembly Linking
Assembly linking, sometimes called merging, is the ability to merge multiple assemblies into one or more output assemblies. This can make an application even smaller and simplify deployment scenarios. When combined with obfuscation and pruning, assembly linking provides a powerful packaging solution for .NET applications.
6. How are we going to do it?

Obfuscators used in .NET

  • Salamander .NET Obfuscator
  • Spices .NET Obfuscator
  • DotFuscator

    Salamander .NET Obfuscator
§Remotesoft's Salamander .NET Obfuscator provides both a GUI environment (Remotesoft .NET Explorer) for exploring and obfuscating .NET applications.
Salamander .NET Obfuscator operates directly on your original binary exe and dll files, without altering debug and line number information. This makes source-level debugging easy; you can just drop the obfuscated assembly in place of the original, invoke the debugger, and go into your original source code
Overall, Salamander .NET Obfuscator appears to work well and the user interface makes a good deal of data on your assemblies readily accessible.
Dotfuscator - Introduction
Dotfuscator is an obfuscator, pruner, linker, and watermarker for .NET applications. It is a key component of a Secure .NET Software Development Life Cycle Process. It adds a new level of protection and application efficiency to any .NET application.
image

7. DotFuscator How to use dotfuscator
1. To open a DotFuscator you need to start up Visual Studio .Net.
Then you will be able to start up DotFuscator Community Edition.
2. All Visual Studio Programs → Microsoft 2005 → Visual Studio Tools → Dotfuscator Community Edition
image
3. Once the “Dotfuscator Community Edition” is clicked. The Dotfuscator application will startup.
image
4. Click on “input” tab and provide the dll/exe file that we have created as input.
image
5. Once the File (dll) has been taken as input, press Ctrl+B to Build the Project. You can use File → Build for the same. The result of the build can visible in output tab.
image
7. Alternatives for Legal protection
  • License agreements – EULA
  • Copyright
  • Patents
      –Dash-O example
  • DMCA and DeCSS
  • Lots of very nasty laws coming
      –Life imprisonment, P2P attacks
8. Conclusion

  • Protecting software is as important as protecting hosts
  • Watermarking, tamper-proofing and obfuscation are important tools for protecting software
  • However, no technique can prevent all attacks
  • Goal is to increase the cost for the attacker
  • Please Mail me if you need PPT version of this Article msdotnetsupport.blogspot@live.com

Thursday, 28 August 2014

Common C# Interview Questions & Answers

1:  Write me a function that receives three integer inputs for the lengths of the sides of a triangle and returns one of four values to determine the triangle type (1=scalene, 2=isosceles, 3=equilateral, 4=error). Generate test cases for the function assuming another developer coded the function 

Answer:

  int GetCubicType(int Height, int Width, int Length)
    {
        if (Height < 0 || Width < 0 || Length < 0)
            return 4;
        else
        {
            if ((Height == Width) && (Height == Length))

                return 3;
            else
                if ((Height == Width) || (Width == Length) || (Length == Width))

                    return 2;
                else
                    return 1;
        }
    }



2: Implement a circular queue of integers of user-specified size using a simple array. Provide routines to initialize(), enqueue() and dequeue() the queue. Make it thread safe.

Answer:


using System;
using System.Threading;

namespace Test
{

    /// <summary>
    /// Summary description for CircularQueue
    /// </summary>
    public class CircularQueue
    {
        private int head;
        private int tail;
        private int[] queue;
        private int length;
        static Object QueueLock = new Object(); // will be used to make the Queue thread safe

        /// <summary>
        /// Queue constructor
        /// </summary>
        /// <param name="Length"> Queue needed Length</param>
        public CircularQueue(int Length)
        {

            Initialize(Length);

        }

        /// <summary>
        /// Empty Constructor for our test Cases
        /// </summary>
        public CircularQueue()
        {

        }

        /// <summary>
        /// Initializes the Queue to a specific given length
        /// </summary>
        /// <param name="Length"> The ne</param>
        private void Initialize(int Length)
        {
            head = tail = -1;
            this.length = Length;
            queue = new int[Length];
        }

        /// <summary>
        ///  Adds a new int element to the end of the Queue
        /// </summary>
        /// <param name="value"> The integer vvalue of the element to be queued</param>
        /// <returns>The index of the queued element or -1 on failure</returns>
        public int Enqueue(int value)
        {
            lock (QueueLock)
            {
                if ((head == 0 && tail == length - 1) || (tail + 1 == head))
                {
                    
                    return -1; // Queue is full
                }
                else
                {


                    if (tail == length - 1)
                        tail = 0;
                    else
                        tail++;

                    queue[tail] = value;
                  
                    if (head == -1)
                        head = 0;

                    return tail;
                }

            }
        }

        /// <summary>
        /// Gets the first element's value in the queue and removes it
        /// </summary>
        /// <returns> The element's value or -1 if the queue is empty</returns>
        public int Dequeue()
        {
            lock (QueueLock)
            {
                int value;

                if (head == -1)
                {
                    value = -1;
                }
                else
                {
                    value = queue[head];
                    queue[head] = 0;

                    if (head == tail)
                        head = tail = -1;
                    else
                        if (head == length - 1)
                            head = 0;
                        else
                            head++;
                }

                return value;
            }
        }

        /// <summary>
        /// Gets a formatted string of the queue elements
        /// </summary>
        /// <returns>Queue elements</returns>
        public string ViewQueueElements()
        {
            lock (QueueLock)
            {
                int i;
                string result = " Queue Emelemnts: ";
                if (head == -1)
                {
                    result = " No Elements Found !";
                }
                else
                {
                    if (tail < head)
                    {
                        //for(i = head; i <= size - 1; i++)
                        for (i = 0; i <= length - 1; i++)
                            result += queue[i] + " ";
                    }
                    else
                        //for(i = head; i <= tail; i++)
                        for (i = 0; i <= tail; i++)
                            result += queue[i] + " ";


                }
                return result + "\n";
            }
        }


        /// <summary>
        /// For Console Application Test
        /// </summary>
        public void StartConsoleTest()
        {
            Initialize(3);
            Enqueue(1);
            Console.WriteLine();
            Console.Write(ViewQueueElements());
            Enqueue(2);
            Console.WriteLine();
            Console.Write(ViewQueueElements());
            Enqueue(3);
            Console.WriteLine();
            Console.Write(ViewQueueElements());
            Dequeue();
            Console.WriteLine();
            Console.Write(ViewQueueElements());
            Dequeue();
            Console.WriteLine();
            Console.Write(ViewQueueElements());
            Dequeue();
            Console.WriteLine();
            Console.Write(ViewQueueElements());
            Console.WriteLine();
          
          



        }


    }

    class Program
    {
        static void Main(string[] args)
        {
            CircularQueue circularQueue = new CircularQueue();

            Thread[] threads = new Thread[1]; // you can use any number of threads

            for (int i = 0; i < threads.Length; i++)
            {
                threads[i] = new Thread(new ThreadStart(circularQueue.StartConsoleTest));
            }

            for (int i = 0; i < threads.Length; i++)
            {
                threads[i].Start();
            }
          
            Console.WriteLine();
            Console.Write(" Press any key to continue...");
            Console.WriteLine();
            Console.ReadLine();
        }
    }
}


3: Memory model and generations

Offer a brief description (no more than 5-10 sentences) on the .NET memory model; identify it’s major features; identify generations and how they relate to the memory model and finally, what implications the memory model has for interoperability with legacy systems and code.
Memory model:  It’s the abstraction that makes the reality of today’s exotic hardware comprehensible to software developers.
The reality of hardware is that CPUs are renaming registers, performing speculative and out-of-order execution, and fixing up the world during retirement.  Memory state is cached at various levels in the systems.
The .NET memory model (on the .NET Framework) guaranteed that for certain types (most notably primitive integers and references) operations were guaranteed to be atomic.

Major Features:
  1. The compiler is free to re-order instructions.
  2. The CPU is free to re-order instructions.
  3. Word-sized reads and writes are atomic. Arithmetic and other operations are not atomic because they involve a read, compute, then write.
  4. Word-sized reads from memory will always retrieve the newest value. But most of the time you don't know if you're actually reading from memory.
  5. A full memory barrier stops (1) and (2). Most compilers allow you to stop (1) by itself.
  6. The volatile keyword ensures you're reading from memory - (4).
  7. The interlocked operations (the lock prefix) allow multiple operations to be atomic. For example, a read + write (InterlockedExchange). Or a read + compare + write (InterlockedCompareExchange). They also act as memory barriers, so (1) and (2) are stopped. They always write to memory (obviously), so (4) is ensured.

4: Destructors

Define destructors, where and why they should be used and what implications they have in relation to finalizers.

Destructors are parameterless class methods (ex: ~ClassName() {}) that work on dumping and releasing the unmanaged resources used by the objects initiated from these classes, A class can have only one destructor and a class destructor can’t be called but it is invoked automatically.
Actually, we use destructors to do extra work on releasing unmanaged resources such as files and network connections; All the other managed resources are released automatically by the .Net Framework CLR using the finilizers that must be invoked in the destructors after we release the unmanaged resources.

5: Exceptions

What is an exception, what is the general pattern for using exceptions and why are they superior to return values?
Exception is a runtime error.
We use the try catch finally statements for exceptions handling, when an exception is thrown, The CLR returns an objects of Exception Type Class such InvalidOperationException for dividing by zero operations.
Every exception object returned has common properties to help us to identify and handle it such as the “Message” property that contains the runtime error message and the “StackTrace” that contains the full path of processing error to refer to the command that caused it.

6: Private Constructors

Can you have a private constructor? If so what would it be used for?
Yes, I used private constructors to control the objects initiation to apply the creational design patterns such as the factory pattern with a GetObject() method as the only public method to initiate objects in addition to singletons and other creational patterns.

7: C#

Difference between Copy and Clone

What is the difference between a copy and a clone in C#? Where does the ICloneable interface come in and what are the issues with it?
Copy: is used to copy the object’s complete structure as well as data.
Clone: is used to copy the object’s structure of a data only.
ICloneable can be found in the “System” namespace.
The problem with ICloneable is that it does not provide enough information.  There is no way to know whether a Clone of an object will be a deep or shallow copy of the original, etc; In addition there is no Generic Types support as there is no “ICloneable<T>”.


8: Thread Safety
What is the difference between the ‘lock’ keyword and a monitor class? Write a class that demonstrates their use to protect access to a variable.
Lock is a simplified version of the monitor. Actually behind the scenes is doing the same thing.
This is an example developed for the last question of the MT Prospect Screen.doc
  public class CircularQueue
    {
        private int head;
        private int tail;
        private int[] queue;
        private int length;
        static Object QueueLock = new Object(); // will be used to make the Queue thread safe

        /// <summary>
        /// Queue constructor
        /// </summary>
        /// <param name="Length"> Queue needed Length</param>
        public CircularQueue(int Length)
        {

            Initialize(Length);

        }

        /// <summary>
        /// Empty Constructor for our test Cases
        /// </summary>
        public CircularQueue()
        {

        }

        /// <summary>
        /// Initializes the Queue to a specific given length
        /// </summary>
        /// <param name="Length"> The ne</param>
        private void Initialize(int Length)
        {
            head = tail = -1;
            this.length = Length;
            queue = new int[Length];
        }

        /// <summary>
        ///  Adds a new int element to the end of the Queue
        /// </summary>
        /// <param name="value"> The integer vvalue of the element to be queued</param>
        /// <returns>The index of the queued element or -1 on failure</returns>
        public int Enqueue(int value)
        {
            lock (QueueLock)
            {
                if ((head == 0 && tail == length - 1) || (tail + 1 == head))
                {
                   
                    return -1; // Queue is full
                }
                else
                {


                    if (tail == length - 1)
                        tail = 0;
                    else
                        tail++;

                    queue[tail] = value;
                  
                    if (head == -1)
                        head = 0;

                    return tail;
                }

            }
        }

        /// <summary>
        /// Gets the first element's value in the queue and removes it
        /// </summary>
        /// <returns> The element's value or -1 if the queue is empty</returns>
        public int Dequeue()
        {
            lock (QueueLock)
            {
                int value;

                if (head == -1)
                {
                    value = -1;
                }
                else
                {
                    value = queue[head];
                    queue[head] = 0;

                    if (head == tail)
                        head = tail = -1;
                    else
                        if (head == length - 1)
                            head = 0;
                        else
                            head++;
                }

                return value;
            }
        }

        /// <summary>
        /// Gets a formatted string of the queue elements
        /// </summary>
        /// <returns>Queue elements</returns>
        public string ViewQueueElements()
        {
            lock (QueueLock)
            {
                int i;
                string result = " Queue Emelemnts: ";
                if (head == -1)
                {
                    result = " No Elements Found !";
                }
                else
                {
                    if (tail < head)
                    {
                        //for(i = head; i <= size - 1; i++)
                        for (i = 0; i <= length - 1; i++)
                            result += queue[i] + " ";
                    }
                    else
                        //for(i = head; i <= tail; i++)
                        for (i = 0; i <= tail; i++)
                            result += queue[i] + " ";


                }
                return result + "\n";
            }
        }

    }



9: The ‘using’ keyword

Write some code that highlights the two primary uses of the ‘using’ keyword.
What are the benefits?
1)      using System;
Enables accessing the namespace public member for reusability.
2)   using (SqlConnection connection = new SqlConnection(""))
        {
            SqlCommand command = connection.CreateCommand();
            command.CommandText = "sp_GetData";
            command.CommandType = CommandType.StoredProcedure;
            connection.Open();
            object result = command.ExecuteScalar();
        }
Provides a convenient syntax that ensures the correct use of IDisposable objects.

10: Classes and Interfaces

Explain briefly the difference between sealed classes; classes; abstract classes and interfaces.
 Classes: are strongly typed types that can be inherited and initiated, it can implement multiple interfaces but it inherits only one class type even if this class is an abstract class.
Sealed Classes: a type of classes that does not support inheritance, so sealed class can’t be inherited.
Abstract Classes: a type of classes that does not support objects initiations, so abstract classes can’t be initiated.
Interfaces: are not types, does not contain code implementations, contains signatures only for methods/properties and variables, can’t have access modifiers, can’t be initiated but can be implemented by classes as mentioned.


11: Implement a Singleton

Show a quick implementation of a singleton. What are the benefits? What are the problems?

public sealed class Singleton
{
    static Singleton instance=null;
    static readonly object padlock = new object();

    Singleton()
    {
    }

    public static Singleton Instance
    {
        get
        {
            lock (padlock)
            {
                if (instance==null)
                {
                    instance = new Singleton();
                }
                return instance;
            }
        }
    }